Kerberos Single Sign On and LDAP Authorization to Apache

Introduction

We have various web servers running Apache on CentOS 5.5. We have approximately 200 users who authenticate to the University domain every morning when they sit down at their Windows computers  and log-in. It would be great if we could “pass-through” that authentication to the Apache web servers so that our users do not have to log in again. Second, we want to check that they are authorized to access various resources on the web server. The first part, SSO authentication, is handled via mod_auth_kerb; the second part, authorization to use particular resources, is handled via mod_authnz_ldap. Mod_authnz_ldap is bundled with Apache 2.2. We will have to build a new version of mod_auth_kerb from source to get a feature that we need to make this work. While this has been documented in a number of places on the web, it took me a long time to get all of the pieces to work together, so I’m going to document our approach.

I’ll start with a list of some of the resources that I consulted while getting this to work:

My notes should be considered as a supplement to their work, and not a replacement for it. I am not an expert in this area by any possible stretch of the imagination.

Initial Configuration

I configured a Windows XP SP3 machine and added it to our domain. I also configured a CentOS 5 server . I did a yum groupinstall of “Web Server” and “Windows File Server”. I also installed the following packages on the CentOS box:

  • krb5-libs-1.6.1-36.el5_5.4
  • krb5-workstation-1.6.1-36.el5_5.4
  • krb5-devel-1.6.1-36.el5_5.4
  • pam_krb5-2.2.14-15
  • krb5-server-1.6.1-36.el5_5.4
  • mod_auth_kerb-5.1-3.el5 – CAVEAT: mod_auth_kerb 5.1 does not work in our environment, as discussed below. You can remove the mod_auth_kerb rpm. We will replace it with a mod_auth_kerb built from source.

On the Windows workstation, I installed:

  • Windows Server 2003 Administration Tools Pack
  • Windows Resource Kit Tools for Windows 2003.

Our Windows servers are running Windows 2003. I am a sub-admin on our Windows domain.

Configuration files

On the CentOS box, I created a file /etc/krb5.conf that looks like this:

[libdefaults]
    default_realm = EU.EMORY.EDU
[domain_realm]
    eu.emory.edu = EU.EMORY.EDU
[realms]
  EU.EMORY.EDU = {
           default_domain = eu.emory.edu
           kdc = DOMAINCONTROLLER.EU.EMORY.EDU:88
           admin_server = DOMAINCONTROLLER.EU.EMORY.EDU
   }

This works for us. Make sure that Kerberos is working from the Linux machine before you do anything else – make sure that you can do a “kinit yourname@YOURKERBEROSREALM” to test that your Linux box is talking to the Windows Kerberos server. The command “klist” should show that your account received an initial ticket, all as shown in step five of the Groims article. Be aware that Kerberos realms are always typed in UPPER case letters.

Working on the Windows client

As is discussed in the articles referenced above, it is necessary to connect to the Windows domain for the next part. Every kerberized host (each Apache server) must have a corresponding service principal in Active Directory. This is a two-step process. You create a user in AD, and then you use ktpass from the Windows machine to map the AD user to the HTTP service and create a keytab file that will be installed on the kerberized host.

This can be done from a domain member workstation; you do not need to be logged into the domain controller for this. I followed the instructions in Scott Lowe’s blog, referenced above. It is important to follow his advice to create a user account and not a computer account. Each Apache server needs a user account, as mentioned above. You may be tempted to create a computer account. It doesn’t seem to work. Create a user account instead.

I am a domain sub-admin within our organization. I do not have rights to create users in the main “People” container for our Active Directory tree. I do have the ability to create users within a User OU that is part of our local OU and that’s what I did. There are a couple of gotchas that might bite the novice (like me):

  • Follow the advice to create a user for the service account. Mr. Lowe’s naming scheme makes sense. We created a user called “http-els4182” to be the service principal for the HTTP server running on els4182.
  • Create the account using the ktpass command as documented in the resources above.
    • ktpass -princ HTTP/els4182.law.emory.edu@EU.EMORY.EDU -mapuser http-els4182 -crypto rc4-hmac-nt -ptype KRB5_NT_SRV_HST -pass CHOOSEPASSWORD -out http-els4182.keytab
  • Note that Mr. Lowe and Mr. Groims use different types of encryption. The method suggested by Mr. Groims is supposed to be better. I am not a security guru, but you should probably use rc4-hmac-nt if possible.
  • Pay attention to the “-out” switch. It will fail silently if you point it at a directory that doesn’t exist. It’s probably fine to create the file in the current directory, but if you don’t like that idea, point it to your desktop or similar.

At this point, you should be able to check that the service principal was properly mapped to the user account by doing this:

  • cd c:program filessupport tools
  • setspn.exe -L ADUSERNAME

In our example above, you would type setspn.exe -L http-els4182. You’ll get back something like this:

Image of screen capture of setspn

This shows that the service principal has been correctly configured.

Working on the Linux Server

For the second half of this exercise, you will need a newer version of the mod_auth_kerb than the one that is available in the repositories for CentOS. The reason is that the 5.1 version of mod_auth_kerb passes through username@REALM as the username. That doesn’t match our user names. As a result, Kerberos will succeed and the user will be authenticated; however, authorization will always fail. As discussed in the comments to this article, that was fixed in version 5.4 of mod_auth_kerb and a new option, KerbLocalUserMapping was added to mod_auth_kerb. It strips the REALM information from the username, allowing LDAP authorization to work.

Here’s how to take care of installing mod_auth_kerb:

  • Make sure that you have httpd-devel installed: yum install httpd-devel
  • Download the source to the latest version of mod_auth_kerb. On the server, do something like:
  • Uncompress the package: tar xvfz mod_auth_kerb-5.4.tar.gz
  • cd mod_auth_kerb-5.4
  • I added /usr/sbin/ to my path so that ./configure would be able to find apxs and I turned off krb4 support:
    • export PATH=$PATH:/usr/sbin
    • ./configure –with-krb4=no
    • make
    • (as root) make install
  • Stop and start the httpd server and verify that there are no errors.

Next, I created a new configuration file for Apache, located in /etc/httpd/conf.d/ . I named the file auth_kerb.conf; however, the naming is up to you so long as it ends in .conf. Here are the contents of that file. You will need to edit it as appropriate:

Alias /private/ /var/www/html/private/

<Location /private/>
Options Indexes
SSLRequireSSL
AuthType Kerberos
  AuthName "Emory Law Kerberos Login"
  KrbMethodNegotiate On
  KrbMethodK5Passwd On
  KrbAuthRealms EU.EMORY.EDU EMORY.EDU
  KrbServiceName HTTP
  Krb5KeyTab /etc/httpd/conf/els4182.keytab
  KrbVerifyKDC off
  KerbLocalUserMapping on
  require valid-user
</Location>

Refer to some of the references cited above for the rationale for the options. Basically, you’re configuring this location to require SSL and you’re telling Kerberos to fall back to basic authentication if the “negotiate” method of authentication fails. What this means is that, if you’re using Firefox on a Mac (and you aren’t using Kerberos), you’re going to see a standard basic authentication prompt asking you to enter your username and password. I have added KrbVerifyKDC off, because our Kerberos server uses self-signed certificates. I’ve added the critical KerbLocalUserMapping on section to make sure that Kerberos passes the username only into Apache rather than the username@REALM. This is important if you’re doing additional authorization via LDAP as discussed below. Finally, “require valid-user” means that anyone with an Active Directory account can access this portion of the web-site. We’ll limit that access via LDAP in a minute. At this point, you need to get the keytab file that you created on the Windows client up to the Linux host using scp or some other method. I chose to put the keytab in /etc/httpd/conf/els4182.keytab as suggested by Lowe. Once the keytab is in the right location, change its ownership to the apache user and make it read-only to that user:

# chown apache.apache /etc/httpd/conf/els4182.keytab
# chmod 400 /etc/httpd/conf/els4182.keytab

As suggested by Groims, test using kvno and klist – although I used a slightly different klist command:

# kvno HTTP/els4182.law.emory.edu@EU.EMORY.EDU
# klist -ke /etc/httpd/conf/els4182.keytab

By using “-k”, you can see the keys in the keytab file.

At this point, you should be able to fire up Apache and check access to the directory via Kerberos from a properly configured Windows machine – both IE and Firefox will require some adjustments before they support SSO via Kerberos.

If this works for you, rejoice. If not, try setting the Apache log level to debug. Also, take SSL out of the equation by turning it off. At this point, you’ve now (hopefully) gotten single sign-on authentication working. Once everything is the way that you want it, you may want to add in a redirect that forces http:// traffic to https:// .

Now it’s time to work on group-based authorization. For that we need to configure mod_authnz_ldap.

Authorization with mod_authnz_ldap

Adding group support requires just a few changes. First, it is critical that you edit /etc/openldap/ldap.conf to add this line:

REFERRALS off

Do this now. Otherwise, this will never work and you will waste half your day trying to figure out why LDAP doesn’t work. Do not edit /etc/ldap.conf. On CentOS or RHEL, you must edit /etc/openldap/ldap.conf.

Next, add the following after the Kerberos settings in auth_kerb.conf, but still within the <Location> section:

AuthLDAPURL "ldaps://DOMAINSERVER.eu.emory.edu:636/dc=eu,dc=emory,dc=edu?cn?sub?(objectClass=user)" NONE
  AuthLDAPBindDN "cn=LDAPSERVICEACCOUNT,ou=users,ou=law,dc=eu,dc=emory,dc=edu"
  AuthLDAPBindPassword "LDAPSERVICEACCOUNTPASSWORD"
  require ldap-group cn=g law all-law,ou=global groups,ou=law,dc=eu,dc=emory,dc=edu

And that should do it.

Conclusion

Well, there you have it. Authentication via Kerberos and Authorization via groups in LDAP. This is harder to configure than one would expect. However, the result is very nice. Stay tuned for a short article on preparing Firefox and IE to take advantage of the Kerberized web server for SSO.

If this works for you, or even if it doesn’t, please let me know in the comments. Also, a  huge thank you to all of the people who were kind enough to document their work on this. Thanks!

Enhanced by Zemanta
Advertisements

3 thoughts on “Kerberos Single Sign On and LDAP Authorization to Apache

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s