Active Directory and Apache Kerberos authentication
This article uses Windows 2003R3 as a KDC, but the exact same setup works with Windows 2008 SP1. The only requirement in case of Windows 2008 is a sufficiently recent Samba installation. In my case, samba 3.4.0-pre1 has been used in both 2003 and 2008 environments.
Introduction
In this short tutorial we'll set up Kerberos and Apache in a Windows 2003 Active Directory forest. It is required that you know your way around with Debian, Apache configuration and not much more ;)
Initial setup
In this article I'll explore how to set up an Apache web server on a Linux Debian box (squeeze testing as of 05/2009) with kerberos authentication integrated with Active Directory on Windows 2003R2. The domain name that I used for this test is: int.test. Three machines make up this small lab:
- Domain Controller and Kerberos KDC - Windows Server 2003R2 - pdc.int.test (172.16.11.12)
- Web Server - Debian Squeeze (as of 05/2009) - www.int.test (172.16.11.16)
- Client1 - Windows XP Professional - client1.int.test (172.16.11.252)
I'll assume that AD is already set up on pdc.int.test and that all the clients and the web server point to it as their DNS server. The first necessary step is to have the DNS zone and the corresponding reverse zone in place:
Once all the DNS business is taken care of (do not forget the reverse PTR pointers), the web server needs to be properly configured, starting with the installation of all the needed packages:
apt-get install apache2-mpm-prefork libapache2-mod-auth-kerb krb5-config krb5-clients krb5-user samba-client openntpd
NTP
Let's make sure that the clocks between the webserver and the DC are in sync. Edit /etc/openntpd/ntpd.conf _and verify that there is a single line containing the DC as ntp server: _server pdc.int.test. Check in /var/log/syslog that the synchronization took place [1] :
May 8 22:46:38 www ntpd[3422]: peer 172.16.11.152 now valid May 8 22:47:59 www ntpd[3422]: clock is now synced
Kerberos
Once time synchronization is taken care of (Kerberos is very sensible about reliable and synchronized clocks), we need to join the machine to the new Active Directory. First let's configure the underlying kerberos libraries in /etc/krb5.conf:
[libdefaults] default_realm = INT.TEST kdc_timesync = 1 ccache_type = 4 forwardable = true proxiable = true fcc-mit-ticketflags = true default_keytab_name = FILE:/etc/krb5.keytab [realms] int.test = { kdc = pdc.int.test master_kdc = pdc.int.test admin_server = pdc.int.test default_domain = int.test } [domain_realm] .int.test = INT.TEST int.test = INT.TEST
If everything is set up correctly, you should be able to authenticate to AD via kerberos:
www:~# kinit Administrator Password for Administrator@INT.TEST:
Double-check that your TGT is correctly set up:
www:~# klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: Administrator@INT.TEST Valid starting Expires Service principal 05/08/09 22:57:48 05/09/09 08:57:52 krbtgt/INT.TEST@INT.TEST renew until 05/09/09 22:57:48
Samba
Once Kerberos is in place we'll configure samba. The file _/etc/samba/smb.conf _should contain the following:
netbios name = www realm = INT.TEST security = ADS encrypt passwords = yes password server = pdc.int.test workgroup = INT
Let's join the domain [2]:
www:~# net ads join -U Administrator Using short domain name -- INTTEST Joined 'WWW' to realm 'int.test'`
Keytab
Now that most of the groundwork is done and the web server joined the AD domain correctly, we need to get the service keys in a keytab to be used by apache. Note that most tutorials suggest to use ktpass.exe on windows. I find this approach much more complex and error-prone (i.e. something like ktpass -princ HTTP/www.int.test@INT.TEST -mapuser http-linux-server -crypto DES-CBC-MD5 -ptype KRB5_NT_PRINCIPAL -mapop set +desonly -pass password -out c:\server.keytab then copying the file to the linux box, etc.).
Thanks to samba this can be easier:
www:~# net ads keytab add HTTP -U administrator Processing principals to add... Enter administrator's password:
Now in _/etc/krb5.keytab _there are the service principals for HTTP/www.int.test. In order to verify it you can use the ktutil tool:
www:~# ktutil ktutil: rkt /etc/krb5.keytab ktutil: l slot KVNO Principal ---- ---- --------------------------------------------------------------------- 1 19 HTTP/www.int.test@INT.TEST 2 19 HTTP/www.int.test@INT.TEST 3 19 HTTP/www.int.test@INT.TEST 4 19 HTTP/www@INT.TEST 5 19 HTTP/www@INT.TEST 6 19 HTTP/www@INT.TEST
We also need to give permission to apache to read this keytab file:
www:~# chmod 740 /etc/krb5.keytab www:~# chgrp www-data /etc/krb5.keytab
It's important to understand that the above solution only makes sense if apache is the only kerberized service. If more than apache is present it makes sense to have separated keytabs with appropriate permissions.
Apache
Make sure the mod_auth_kerb module is active with a2enmod auth_kerb.
<Location /secured> AuthType Kerberos AuthName Kerberos Login KrbMethodNegotiate On KrbMethodK5Passwd On KrbAuthRealms INT.TEST Krb5KeyTab /etc/krb5.keytab require valid-user </Location>
Make sure that the relative dir_ secured _exists and that it contains an ad hoc index.html so we can verify the successful authentication. Once the testing phase is completed, I tipically switch off the KrbMethodK5Passwd option, so users do not get promptet for authentication if for some reason the Kerberos authentication fails.
Set up the client
On the Windows XP Pro client (client1.int.test) we can test this kerberized Apache setup.
Firefox
Mozilla Firefox is a bit simpler to set up. You need to add the domain int.test to the options network.negotiate-auth.trusted-uris and network.negotiate-auth.delegation-uris.
Once this is done, we just need to browse to the page where Kerberos authentication is forced: www.int.test/secured
** **
Internet Explorer 8
Internet Explorer is a little bit more difficult to setup. With this I mean that there are a few more spots where things can go wrong. First you need to go in Tools, Internet Options, Advanced and all the way to the bottom you need to make sure that Enable Integrates Windows Authentication is active (it might require a restart):
You will also need to add .int.test ** to the Intranet Zones*. (Note that Integrated Windows Authentication does not work on home variants of Microsoft Operating Systems)
Under Tools, Internet Options, Security, Custom Level verify that Automatic logon only in Intranet zone is selected.
Once all these steps are taken care of you'll see the same HTML page as Firefox when going to http://www.int.test/secured
Footnotes
[1] You should make sure that the Domain Controller that has the PDC Emulator role in your domain synchronizes the time with an NTP box somewhere on the net or via a special time HW device.
[2] If you encounter a GSS error related to Stream modified, it might be due to a bug in the kerberos 1.7beta libs (It's been fixed in beta3)