Using Kerberos for single sign on is a nice thing but one feels uncomfortable that only a password grants access to all services. One can use smart cards and public key cryptography to achieve Two factor authenticaton which makes things considerably safer. In Kerberos terms this is called pkinit. To get there, several steps are necessary:
- Creating the PKI
- Setting up the KDC
- Setting up the user part
- Putting things on the smart card
Creating the PKI
If you don't already have certificates hxtool is the simplest thing to create them:
Create the Certificate Authority (CA):
$ hxtool issue-certificate --self-signed --issue-ca --generate-key=rsa --subject="CN=CA,DC=ms20,DC=nix" --lifetime=10years --certificate="FILE:ca.pem"
Create the KDCs certificate:
$ hxtool issue-certificate --ca-certificate=FILE:ca.pem --generate-key=rsa --type="pkinit-kdc" --pk-init-principal="krbtgt/MS20.NIX@MS20.NIX" --subject="uid=kdc,DC=ms20,DC=nix" --certificate="FILE:kdc.pem"
Create the Certificate for a User agx@MS20.NIX:
$ hxtool issue-certificate --ca-certificate=FILE:ca.pem --generate-key=rsa --type="pkinit-client" --pk-init-principal="agx@MS20.NIX" --subject="uid=agx,DC=ms20,DC=nix" --certificate="FILE:user.pem"
In the above setup, hxtool puts the certificate and the private key into one file, so extract the lines between:
-----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY-----
from ca.pem, store it away in ca.key ant put it at a save location, remove these lines from ca.pem then. Don't put ca.key on the KDC - you only need it to create new certificates. The resulting ca.pem is the save to copy around.
Setting up the KDC
You need to enable pkinit in /etc/heimdal-kdc/kdc.conf and tell the KDC where to find it's own identity (pkinit_identity) as well as the trust anchors (pkinit_anchors). For simplicity we use our new CA as the only trust anchor so only certificates signed by this ca are valid for the KDC:
enable-pkinit = yes pkinit_identity = FILE:/etc/heimdal-kdc/pkinit/kdc.pem pkinit_anchors = FILE:/etc/heimdal-kdc/pkinit/ca.pem # don't allow proxy certificates pkinit_allow_proxy_certificate = false pkinit_win2k_require_binding = yes
Copy ca.pem and kdc.pem to the above locations. Make sure kdc.pem is only readable by root since it contains a private key.
Setting up the user part
The client needs to know about our CA too since it needs to identify the KDC. This is setup in /etc/krb5.conf:
[libdefaults] pkinit_anchors = FILE:/etc/ssl/certs/ca.pem
Copy ca.pem to the above location. Also copy user.pem to ~ and split out the private key part into a separate file user.key (the steps are the same as explained for the CA above). You can the test your installation with:
$ cd ~ $ kinit -C FILE:user.pem,user.key agx@MS20.NIX $ klist Credentials cache: FILE:/tmp/krb5cc_0 Principal: agx@MS20.NIX Issued Expires Principal Jun 20 14:52:27 Jun 21 00:52:27 krbtgt/MS20.NIX@MS20.NIX
Putting things onto the smart card:
First Install opensc and make sure your smart card is recognized:
$ opensc-tool -n CardOS M4
I used an empty Aladdin eToken Pro which I wiped completely before adding the keys:
$ pkcs15-init -E $ pkcs15-init -C -p pkcs15+onepin $ pkcs15-init --store-private-key user.key --auth-id 01 $ pkcs15-init --store-certificate user.pem --auth-id 01 # Lets see if it worked: $ kinit -C PKCS11:/usr/lib/opensc/opensc-pkcs11.so agx@MS20.NIX Credentials cache: FILE:/tmp/krb5cc_0 Principal: agx@MS20.NIX Issued Expires Principal Jun 20 14:52:27 Jun 21 00:52:27 krbtgt/MS20.NIX@MS20.NIX
That's it. The steps above are quiet terse but this should get you started. Libpam-krb5 has pkinit support so you can use this during logon.