Recently, I wanted to add single sign on (SSO) functionality to our intranet server, which runs a Debian Linux. Users should be automatically logged in to the website using their Windows user accounts, which are stored in an Active Directory on a Windows Server 2008 R2, without entering their credentials again. To make this work in the described Linux/Windows environment, Kerberos is the method of choice.
Now, after looking at the small bit of configuration that is actually needed to get SSO working, the complete day I spent figuring it out seems like a waste of time 🙂 But while searching the web for answers to all the problems I faced during the initial configuration, I got a feeling that many others had to struggle with Kerberos, too.
Anyway, here is how to make SSO run on Debian Linux against Windows Server 2008 R2, started from scratch:
Make sure to use only the latest packages available, especially the ones regarding Samba and Kerberos. Otherwise Kerberos may not work due to changes in Windows Server 2008. I used the following configuration in /etc/apt/sources.list:
deb http://ftp.de.debian.org/debian/ squeeze main
deb-src http://ftp.de.debian.org/debian/ squeeze main
These are the packages’ versions on my Debian machine:
ii samba 2:3.5.6~dfsg-3squeeze2 SMB/CIFS file, print, and login server for Unix
ii samba-common 2:3.5.6~dfsg-3squeeze2 common files used by both the Samba server and client
ii samba-common-bin 2:3.5.6~dfsg-3squeeze2 common files used by both the Samba server and client
ii krb5-config 2.2 Configuration files for Kerberos Version 5
ii krb5-multidev 1.8.3+dfsg-4 Development files for MIT Kerberos without Heimdal conflict
ii krb5-user 1.8.3+dfsg-4 Basic programs to authenticate using MIT Kerberos
ii libgssapi-krb5-2 1.8.3+dfsg-4 MIT Kerberos runtime libraries - krb5 GSS-API Mechanism
ii libkrb5-3 1.8.3+dfsg-4 MIT Kerberos runtime libraries
ii libkrb5-dev 1.8.3+dfsg-4 Headers and development libraries for MIT Kerberos
ii libkrb53 1.8.3+dfsg-4 transitional package for MIT Kerberos libraries
ii libkrb5support0 1.8.3+dfsg-4 MIT Kerberos runtime libraries - Support library
Install the needed packages and go through the basic configuration as described here:
In my case the basic needed configuration looks like this:
- /etc/krb5.conf
[libdefaults]
default_realm = YOURDOMAIN.COM
[realms]
YOURDOMAIN.COM = {
kdc = DOMAINCONTROLLER.YOURDOMAIN.COM
master_kdc = DOMAINCONTROLLER.YOURDOMAIN.COM
admin_server = DOMAINCONTROLLER.YOURDOMAIN.COM
default_domain = YOURDOMAIN.COM
}
[login]
krb4_convert = true
krb4_get_tickets = false
- /etc/samba/smb.conf
workgroup = YOURDOMAIN
realm = YOURDOMAIN.COM
netbios name = WEBSERVER
security = ADS
idmap uid = 10000-20000
idmap gid = 10000-20000
winbind enum users = yes
winbind enum groups = yes
winbind use default domain = yes
machine password timeout = 0 # needed when using only the machine account as described below
- /var/www/kerberos/.htaccess
AuthType Kerberos
KrbAuthRealms YOURDOMAIN.COM
KrbMethodNegotiate On
KrbMethodK5Passwd On
KrbServiceName HTTP/webserver.yourdomain.com
Krb5KeyTab /etc/krb5.keytab
require valid-user
Now you basically have two choices for Kerberos authentication against the Active Directory: Using a seperate technical user account (which should be the preferred method) or using only the Linux server’s machine account.
Using a seperate technical user account
- (re)join the Linux server to the domain
webserver:~# net ads join -U administrator
Enter administrator's password:
Using short domain name -- YOURDOMAIN
Joined 'WEBSERVER' to realm 'yourdomain.com'
- restart the services
webserver:~# /etc/init.d/samba restart
Stopping Samba daemons: nmbd smbd.
Starting Samba daemons: nmbd smbd.
webserver:~# /etc/init.d/winbind restart
Stopping the Winbind daemon: winbind.
Starting the Winbind daemon: winbind.
- check whether everything works
webserver:~# wbinfo -t
checking the trust secret for domain YOURDOMAIN via RPC calls succeeded
- add a technical user to your Active Directory, e.g. tukerberos with password Kerber0s
- create and attach the needed service principals for the website to the technical user on the domain controller
ktpass -princ HOST/webserver.yourdomain.com@YOURDOMAIN.COM -mapuser tukerberos@YOURDOMAIN.COM -crypto RC4-HMAC-NT -ptype KRB5_NT_PRINCIPAL -pass Kerber0s -out c:\krb5.keytab
ktpass -princ HTTP/webserver.yourdomain.com@YOURDOMAIN.COM -mapuser tukerberos@YOURDOMAIN.COM -crypto RC4-HMAC-NT -ptype KRB5_NT_PRINCIPAL -pass Kerber0s -out c:\krb5.keytab -in c:\krb5.keytab
- copy \\domaincontroller\c$\krb5.keytab to webserver:/etc/krb5.keytab
- set the needed file system permissions on the keytab file
webserver:~# chown root.www-data /etc/krb5.keytab
webserver:~# chmod 0640 /etc/krb5.keytab
- open http://webserver/ in Internet Explorer → the user should be logged in automatically
Using only the Linux server’s machine account
- (re)join the Linux server to the domain (the error message may be ignored for now)
webserver:~# net ads join -U administrator
Enter administrator's password:
Using short domain name -- YOURDOMAIN
Joined 'WEBSERVER' to realm 'yourdomain.com'
[2011/04/19 10:54:35.026049, 0] libads/kerberos.c:333(ads_kinit_password)
kerberos_kinit_password WEBSERVER$@YOURDOMAIN.COM failed: Preauthentication failed
- reset the (newly created) machine account in your Active Directory so the machine’s password is reset to the initial value (i.e. the machine’s hostname, webserver)
- change the machine’s password to a new value (e.g. Kerber0s)
webserver:~# kpasswd webserver
Password for webserver@YOURDOMAIN.COM: webserver
Enter new password: Kerber0s
Enter it again: Kerber0s
Password changed.
- add the needed service principals (e.g. HTTP/webserver, HTTP/webserver.yourdomain.com) to the machine account using adsiedit.msc on your domain controller
- request an initial Kerberos ticket
webserver:~# kinit webserver
Password for webserver@YOURDOMAIN.COM: Kerber0s
- find out the current kvno of the service principal
webserver:~# kvno HTTP/webserver
HTTP/webserver@YOURDOMAIN.COM: kvno = 18
- create a Kerberos keytab file
webserver:~# ktutil
ktutil: addent -password -p HOST/webserver.yourdomain.com@YOURDOMAIN.COM -k 18 -e rc4-hmac
Password for HTTP/webserver.yourdomain.com@YOURDOMAIN.COM: Kerber0s
ktutil: addent -password -p HTTP/webserver.yourdomain.com@YOURDOMAIN.COM -k 18 -e rc4-hmac
Password for HTTP/webserver.yourdomain.com@YOURDOMAIN.COM: Kerber0s
ktutil: wkt /etc/krb5.keytab
ktutil: q
- set the needed file system permissions on the keytab file
webserver:~# chown root.www-data /etc/krb5.keytab
webserver:~# chmod 0640 /etc/krb5.keytab
- open http://webserver/ in Internet Explorer → the user should be logged in automatically
Possible errors and how to fix them
This is how a successful Kerberos login looks in the Apache logfile:
[Tue Apr 19 11:09:04 2011] [debug] src/mod_auth_kerb.c(1628): [client 10.120.22.74] kerb_authenticate_user entered with user (NULL) and auth_type Kerberos
[Tue Apr 19 11:09:04 2011] [debug] src/mod_auth_kerb.c(1240): [client 10.120.22.74] Acquiring creds for HTTP/webserver.yourdomain.com
[Tue Apr 19 11:09:04 2011] [debug] src/mod_auth_kerb.c(1385): [client 10.120.22.74] Verifying client data using KRB5 GSS-API
[Tue Apr 19 11:09:04 2011] [debug] src/mod_auth_kerb.c(1401): [client 10.120.22.74] Client didn't delegate us their credential
[Tue Apr 19 11:09:04 2011] [debug] src/mod_auth_kerb.c(1420): [client 10.120.22.74] GSS-API token of length 163 bytes will be sent back
However, these are all the different error messages I got throughout my initial attempt:
[Mon Apr 18 16:57:30 2011] [debug] src/mod_auth_kerb.c(1101): [client 10.120.22.74] GSS-API major_status:000d0000, minor_status:0000000d
[Mon Apr 18 16:57:30 2011] [error] [client 10.120.22.74] gss_acquire_cred() failed: Unspecified GSS failure. Minor code may provide more information (, Permission denied)
→ wrong file system permissions for /etc/krb5.keytab, i.e. not readable for the webserver’s Linux user
[Mon Apr 18 17:51:54 2011] [debug] src/mod_auth_kerb.c(1101): [client 10.120.22.74] GSS-API major_status:000d0000, minor_status:025ea101
[Mon Apr 18 17:51:54 2011] [error] [client 10.120.22.74] gss_acquire_cred() failed: Unspecified GSS failure. Minor code may provide more information (, Key table entry not found)
→ missing service principal (possibly HTTP/webserver.yourdomain.com@YOURDOMAIN.COM) in /etc/krb5.keytab
[Tue Apr 19 08:40:38 2011] [debug] src/mod_auth_kerb.c(1429): [client 10.120.22.74] Warning: received token seems to be NTLM, which isn't supported by the Kerberos module. Check your IE configuration.
[Tue Apr 19 08:40:38 2011] [debug] src/mod_auth_kerb.c(1101): [client 10.120.22.74] GSS-API major_status:00010000, minor_status:00000000
[Tue Apr 19 08:40:38 2011] [error] [client 10.120.22.74] gss_accept_sec_context() failed: An unsupported mechanism was requested (, Unknown error)
→ the website is not in zone “Local Intranet” in IE or IE is configured incorrectly, see Authentication Uses NTLM instead of Kerberos
[Tue Apr 19 09:31:43 2011] [debug] src/mod_auth_kerb.c(1101): [client 10.120.20.81] GSS-API major_status:000d0000, minor_status:000186a3
[Tue Apr 19 09:31:43 2011] [error] [client 10.120.20.81] gss_accept_sec_context() failed: Unspecified GSS failure. Minor code may provide more information (, )
→ wrong kvno or machine password in /etc/krb5.keytab → recreate the keytab using the correct information
→ OR problem with local Kerberos ticket cache on your workstation, use Kerbtray.exe to purge the ticket cache and open the website in IE again