Kerberos - Service Principals

Kerberos - Service Principals

The specific steps to enable Kerberos for a service can vary a bit, but in general the following is needed:

  • a principal for the service: usually service/host@REALM
  • a keytab accessible to the service wherever it’s running: usually in /etc/krb5.keytab

For example, let’s create a principal for an LDAP service running on the ldap-server.example.com host:

ubuntu@ldap-server:~$ sudo kadmin -p ubuntu/admin
Authenticating as principal ubuntu/admin with password.
Password for ubuntu/admin@EXAMPLE.COM:
kadmin:  addprinc -randkey ldap/ldap-server.example.com
No policy specified for ldap/ldap-server.example.com@EXAMPLE.COM; defaulting to no policy
Principal "ldap/ldap-server.example.com@EXAMPLE.COM" created.

Let’s dig a bit into what is happening here:

  • the kadmin command is being run in the ldap-server machine, not on the KDC. We are using kadmin remotely
  • it’s being run with sudo, the reason will become clear later
  • we are logged in on the server as ubuntu, but specifying a ubuntu/admin principal. Remember the ubuntu principal has no special privileges
  • the name of the principal we are creating follows the pattern service/hostname
  • in order to select a random secret, we pass the -randkey parameter. Otherwise we would be asked to type in a password.

With the principal created, we need to extract the key from the KDC and store it in the ldap-server host, so that the ldap service can use it to authenticate itself with the KDC. Still in the same kadmin session:

kadmin:  ktadd ldap/ldap-server.example.com
Entry for principal ldap/ldap-server.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal ldap/ldap-server.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.

This is why he needed to run kadmin with sudo: so that it can write to /etc/krb5.keytab. This is the system keytab file, which is the default file for all keys that might be needed for services on this host. And we can list them with klist. Back in the shell:

$ sudo klist -k
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   2 ldap/ldap-server.example.com@EXAMPLE.COM
   2 ldap/ldap-server.example.com@EXAMPLE.COM

If you don’t have the kadmin utility on the target host, one alternative is to extract the keys on a different host and into a different file, and then transfer this file securely to the target server. For example:

kadmin:  ktadd -k /home/ubuntu/ldap.keytab ldap/ldap-server.example.com
Entry for principal ldap/ldap-server.example.com with kvno 3, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/home/ubuntu/ldap.keytab.
Entry for principal ldap/ldap-server.example.com with kvno 3, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/home/ubuntu/ldap.keytab.

Note
Notice how the kvno changed from 2 to 3 in the example above, when using ktadd a second time? This is the key version, and it basically invalidated the key with kvno 2 that was extracted before. Everytime a key is extracted with ktadd, its version is bumped and that invalidates the previous ones!

In this case, as long as the target location is writable, you don’t even have to run kadmin with sudo.

Then use scp to transfer it to the target host:

$ scp /home/ubuntu/ldap.keytab ldap-server.example.com:

And over there copy it to /etc/krb5.keytab, making sure it’s mode 0600 and owned by root:root.