I have used the instructions on http://www.grolmsnet.de/kerbtut/ many times because they work. For the record, you do not need to join the linux host to the AD domain, it's ok to do it but not necessary.
First of all, ensure you can kinit from the centos host to your AD realm. You can use your normal user credentials like this:
$ kinit yourusername@ADREALM.TLD
(kinit is part of the krb5-workstation package in centos, by the way)
Enter your password and no news is good news. Run klist and you should see a kerberos ticket there as your AD username. If this step is not successful go back and fix your krb5.conf until it is.
Get rid of that ticket with kdestroy.
Once that works you can create a user account in AD. Ensure that it does not have to change its password and that the password does not expire.
Then we bind the service principal name (spn) HTTP/host.adrealm.tld to that useraccount using setspn.exe on a windows hosts with the management tools or in a domain controller as an admin or account with sufficient privileges:
setspn -A HTTP/host.adrealm.tld username [enter]
Registering ServicePrincipalNames for CN=username,OU=service_accounts,dc=adrealm,DC=tld
HTTP/host.adrealm.tld
Updated object
Now we can generate the keytab for this object using ktpass.exe (still in the windows management host or domain controller):
ktpass -princ HTTP/host.adrealm.tld@ADREALM.TLD -pass xxxxx -mapuser username -Ptype KRB5_NT_PRINCIPAL -out host_adrealm_tld.keytab [enter]
Targeting domain controller: DCname.Adrealm.tld
Successfully mapped HTTP/host.adrealm.tld to username.
Password succesfully set!
Key created.
Output keytab to host_adrealm_tld.keytab:
Keytab version: 0x502
keysize 75 HTTP/host.adrealm.tldl@ADREALM.TLD ptype 1 (KRB5_NT_PRINCIPAL)
vno 3 etype 0x17 (RC4-HMAC) keylength 16 (0x037da0f7493b97966e4a19636304064d)
Transport that file to the centos host and place it with 640 permissions (root:apache) in /etc/httpd/conf.d/ . If selinux is enabled, run restorecon -rv /etc to eventually fix selinux contexts there.
You can verify the keytab file with:
$ klist -k -t host_adrealm_tld.keytab
Keytab name: FILE:host_adrealm_tld.keytab
KVNO Timestamp Principal
---- ----------------- --------------------------------------------------------
3 01/01/70 01:00:00 HTTP/host.adrealm.tld@ADREALM.TLD
And you could even go one step further by using it to log on:
# kinit -k -t host_adrealm_tld.keytab -p HTTP/host.adrealm.tld@ADREALM.TLD
# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: HTTP/host.adrealm.tld@ADREALM.TLD
Valid starting Expires Service principal
11/04/14 21:45:41 11/05/14 07:45:41 krbtgt/ADREALM.TLD@ADREALM.TLD
renew until 11/05/14 21:45:41
In your dns infrastructure (probably in AD dns as well), create an A host.realm.tld pointing to the centos host (if you use samba to join the host it should have created it for you, ensure it is correct).
Ensure your centos hosts has the mod_auth_kerb installed.
Whant that is in place you edit one of the apache conf files of your (virtual) hosts for apache.
In this case, let's protect the folder http://host.adrealm.tld/topsecret:
Alias /topsecret/ "/path/to/topsecret/"
<Directory "/path/to/topsecret/">
AuthType Kerberos
KrbAuthRealms YOURAD.TLD
KrbServiceName HTTP
Krb5Keytab /etc/httpd/conf.d/host_adrealm_tld.keytab
KrbMethodNegotiate on
KrbMethodK5Passwd off
require valid-user
</Directory>
Create the topsecret folder in the filesystem of the centos host. Set a couple of dummy files in there. If you run with selinux enable, ensure that folder has the right security context for apache (if the folder is in /var/www/html it should be righ an running restorecon -rv /var/www/html will eventually fix any selinux problems).
Verify the apache2 syntax passes:
apachectl -t
If you get 'Syntax OK' with warnings about not being able to reliably determine the host fqdn, then you are good to go (you can fix that later if you want, it is not critical). Reload apache:
apachectl graceful
Verify your local firewall allows httpd connexxions.
This should be it. Now you need to configure the clients. If you already have webservers with 'Windows Authentication' in your network then you are set, go to the topsecret url and if you have a valid kerberos ticket you should see the files, otherwise you will get access denied.
Thanks for all your input, guys. We got Microsoft on board, and they helped us debug the authentication process on the AD side. Everything worked as it was supposed to, but failed after thirty minutes.
While we were doing a remote debugging session, on of the participants noticed that the UPN/SPN of the service account was suddenly resat from HTTP/mysite.mycorp.com@MYCORP.COM to service-account@mycorp.com. After a LOT of digging around, including debugging AD replication, we found the culprit:
Someone had made a script that ran periodically (or probably by event, since it was exactly thirty minutes after running ktpass.exe), which updated the UPN/PSN to "ensure cloud connectivity". I do not have any supplemental information on the reasons for doing this.
The script was changed to allow existing UPN/SPN values ending in @mycorp.com, effectively solving the problem.
Tips for debugging issues like this:
- Ensure all the participants in the authentication supports the same encryption types. Avoid DES - it's outdated and insecure.
- Make sure to enable AES-128 and AES-256 encryption on the service account
- Be aware that enabling DES on the service account means "use ONLY DES for this account", even if you enabled any of the AES encryptions. Do a search for UF_USE_DES_KEY_ONLY for details on this.
- Make sure the UPN/SPN value is currect and matches the value in the issued keytab file (i.e. through an LDAP lookup)
- Make sure the KVNO (Key Version Number) in the keytab file matches the on on the server
- Inspect traffic between server and client (i.e. with tcpdump and/or WireShark)
- Enable debugging of authentication on the AD side - inspect logs
- Enable debugging of replication on the AD side - inspect logs
Again, thank you for your input.
Best Answer
If I'm interpreting the error right, I think it means that you have an old version of a key in /etc/apache2/httpd.keytab. Every time the key is changed for a Kerberos principal via kadmin, the version number is incremented and older versions of that key are invalidated.
The
kinit
command/login only shows that the host key inside of /etc/krb5.keytab is intact. This does not necessarily mean that the kvno inside of httpd.keytab is valid and you will need to check it against the KDC.Start a kadmin session against your KDC and invoke
getprinc <principalname>
. Look for "Key: vno", this tells you what the KDC considers to be the version number. If the KDC has a more recent version of the key, you need to re-export this key to the host in question. I would go ahead and check the validity of all the keys in /etc/krb5.keytab while you're at it just to make sure there aren't any other time bombs lurking around.Hopefully this helps!