SSO Heaven

Due to the humidity and heat this past weekend, my wife and I decided to hang out around the house. I was a bit bored at first but then I decided to roll up my sleeves and start to finally wrap my head around the Kerberos architecture and kerberizing services to achieve SSO nirvana; something I’ve been wanting since I first implemented Kerberos authentication a couple of years back.

Background

Back in 2011, I had grown bored with my Windows 2003 AD so I ditched it and implemented OpenLDAP+Kerberos; the former for authorization/identity management and the latter for authentication. I got it all basically working with users/groups in LDAP, user principals and passwords set in the KDC, and Apache setup to perform basic auth back to the KDC. So it all worked, but I didn’t actually kerberize any of the hosts or services on the network; SSH and Apache prompted the user for credentials. I wanted to be able to grab a Ticket Granting Ticket and go.

There were two main things I wanted kerberized: SSH and Apache.

What I learned

First things first: get the foundation working and in this case, like a lot of things, the foundation is DNS along with NTP. The latter was all fine, but my Intranet and KDC were using two different DNS server, with different zones configured in them. For now, I made the two DNS servers have the same zones, each thinking that they are the master. I’ll probably change this at some point down the road as this can only lead to pain.

In order for DNS to be effective, I also had to clean up my hosts files where appropriate so that every client, server, and service all used the same names.

KDC

With the foundation laid, I turned to understanding how Kerberos works in general. As I understand it at this point, making use of a TGT to get you authenticated requires a triangle of trust: the client establishes a trust with the KDC when it gets a TGT, the network services establishes a trust with the KDC via its server’s keytab, and the workstation and network services establish a trust because they both trust the KDC. The part I had never setup was the trust between the various services and the KDC. This is done by host and service principals that can be created on the KDC using kadmin.local and published to the services via a keytab. On the KDC, launch kadmin.local and create the host and SERVICE principals thusly:

addpinc -randkey host/hostname.domain.tld addpinc -randkey HTTP/virtualhostname.domain.tld

Now that the KDC has created the keys it will accept for the services (in this case “HTTP” for Apache and “host” for, among other things, SSH), we have to push these out to the various servers hosting the services. This will establish the trust between the servers hosting the network services and the KDC. Again, on the KDC with kadmin.local:

ktadd -k /tmp/krb5.keytab -glob hostname.domain.tld ktadd -k /tmp/krb5.keytab -glob virtualhostname.domain.tld

The above command with create the keytab file with the keys that will establish the service/KDC trust. You can take a look at what’s in the keytab using klist -kt /tmp/krb5.keytab

Network Services

Move the keytab over to the sever hosting the services and place it in /etc/

Apache

Apply permissions to the keytab such that Apache can read it:

chown root:www-data /etc/krb5.keytab && chmod 640 /etc/kr5b.keytab

The “tricky” part for the Apache config was getting the Directory statement right in the site’s conf file. Things started working when I put in “KrbServiceName HTTP/virtualhost.domain.tld” to specify the principal to use:

<Directory /path/to/web/app/> AuthName "Kerberos" AuthType Kerberos Krb5Keytab /etc/krb5.keytab KrbAuthRealm YOURREALM.TLD KrbMethodNegotiate on KrbMethodK5Passwd off KrbSaveCredentials off KrbVerifyKDC on KrbServiceName HTTP/virtualhostname.domain.tld Require valid-user </Directory>

SSH

To get SSH working, the SSH server needs to be set with “GSSAPIAuthentication yes” in sshd_config and the client needs to be set with “GSSAPIAuthentication yes” and “GSSAPIDelegateCredentials yes” in ssh_config. Grab a TGT with “kinit username”. Connecting with username@hostname.domain.tld should now let you SSH into the server without being prompted for a password. Similarly, after an Apache restart, you should be able to pull up your webpage without auth, provided the web app is configured to allow Apache Basic authentication.

Resources

IBM had a nice page outlining the “minor” Kerberos error codes that I would see in the Apache debug logs and the SSH debug output

The Apache Mod Kerb sourceforge project had a nice writeup of the Apache Directory Kerberos options

This is a personal website. Unless otherwise stated, the content and opinions expressed here are my own and not those of my employer.