Automating Domain join using a user keytab

All the cool Active Directory authentication stuff I wrote about requires machines to be joined into the domain. This process involves entering an administrator's password on every machine that is to be joined, which can be quite cumbersome if you have a large number of machines. In a cloud environment where machines are to be automatically deployed and provisioned, manually entering an admin password is downright unacceptable.

However, since the only step that actually requires the password is the kinit command, there's a way around using passwords: We can simply store a keytab on the box that contains the password, and then use the keytab to authenticate to the domain. Then, we won't require any passwords at all.

Note that you're going to distribute an administrative account's credentials around the domain, so please don't just use the Administrator account for this. Create a special account that only has the privilege to join new computers, but that cannot do anything else. For example, we call this user "machineadm".

First of all, we need to manually create a keytab that contains the correct key. To do this, we need to know the current key version number the domain is using for the user account (this is roughly equivalent to the number of password changes that occurred for this user so far). You can find it using ADSIEdit, or by using ldapsearch. Look for the attribute named msDS-KeyVersionNumber:

$ ldapsearch -Y GSSAPI -H 'ldap://dc.local.lan'  -b 'dc=local,dc=lan' '(sAMAccountName=machineadm)' msDS-KeyVersionNumber
# machineadm, Users, local.lan
dn: CN=machineadm,CN=Users,DC=local,DC=lan
msDS-KeyVersionNumber: 1

So, the key version number is 1, which is also the default if we have simply created the user without ever changing their password.

Now we can create the keytab using ktutil:

$ ktutil
ktutil:  addent -password -p machineadm@LOCAL.LAN -k 1 -e RC4-HMAC
Password for machineadm@LOCAL.LAN: <enter the password>
ktutil:  wkt /etc/krb5.keytab.machineadm
ktutil:  q

The wkt command writes this keytab into a file named /etc/krb5.keytab.machineadm. We can use klist to verify its contents:

$ klist -k -t /etc/krb5.keytab.machineadm
Keytab name: FILE:/etc/krb5.keytab.machineadm
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   1 25.09.2015 14:52:16 machineadm@LOCAL.LAN

This keytab file now needs to be stored in a central location from where it is easily retrievable (e.g. a repository), so it can easily be distributed and used in an automated deployment process.

Once you have the keytab and /etc/krb5.conf set up correctly, using kinit to authenticate as machineadm works like this:

$ kinit -k -t /etc/krb5.keytab.machineadm machineadm

$ klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: machineadm@LOCAL.LAN

Valid starting       Expires              Service principal
25.09.2015 14:52:37  26.09.2015 00:52:37  krbtgt/LOCAL.LAN@LOCAL.LAN
        renew until 26.09.2015 14:52:37

Et voilà, we have successfully authenticated to the domain without using a password! Now we can just proceed with the domain join process and automatically configure the machine to be accessible using a domain user account.