Single Sign-On with Kerberos, Apache's httpd and Linux
WORK IN PROGRESS
Updates:
- 2015-03-05 Testing shows that OK_TO_DELEGATE flag not required for httpd server
Contents
Goal
User's log-in to their workstation or desktop once with their Kerberos username and password. Then, when using their preferred web browser, their credentials are automatically collected from the local Kerberos ticket cache by their browser and passed to the web server to authenticate them and grant them access without them having to supply either their user name or password.
Configuration
Network environment
- Network: 192.168.251.0/24 + 192.168.254.0/24
- Domain: my.desk
Linux Apache httpd server
- Host: exampleweb.my.desk
- Address: 192.168.251.12
- OS: CentOS Linux release 7.0.1406 (Core)
krb5.conf
[logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] dns_lookup_realm = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true rdns = false allow_weak_crypto = true default_realm = AD.UNSW.EDU.AU # default_realm = DOOKEY.DOOKEY # default_realm = MY.DESK # default_ccache_name = KEYRING:persistent:%{uid} [realms] AD.UNSW.EDU.AU = { kdc = ad.unsw.edu.au # admin_server = ad.unsw.edu.au } DOOKEY.DOOKEY = { kdc = win2k8r2ent.my.desk # admin_server = win2k8r2ent.my.desk } MY.DESK = { kdc = kerberos.my.desk # admin_server = kerberos.my.desk } [domain_realm] .my.desk = MY.DESK .ad.unsw.edu.au = AD.UNSW.EDU.AU ad.unsw.edu.au = AD.UNSW.EDU.AU
httpd.conf
ServerRoot "/etc/httpd" Listen 80 Include conf.modules.d/*.conf User apache Group apache ServerAdmin plinich@cse.unsw.edu.au <Directory /> AllowOverride none Require all denied </Directory> DocumentRoot "/var/www/html" <Directory "/var/www/html"> Options None AllowOverride All Require all granted </Directory> ScriptAlias /cgi-bin/ /var/www/cgi-bin/ <Directory "/var/www/cgi-bin"> Options None AllowOverride All Require all granted </Directory> ScriptAlias /cgi-bin-sso/ /var/www/cgi-bin-sso/ <Directory "/var/www/cgi-bin-sso"> Options None AllowOverride All Require all granted </Directory> ErrorLog "logs/error_log" #LogLevel warn LogLevel debug LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%h %p %l %u %t \"%r\" %>s %b" custom CustomLog "logs/access_log" custom TypesConfig /etc/mime.types AddDefaultCharset UTF-8 MIMEMagicFile conf/magic EnableSendfile on IncludeOptional conf.d/*.conf Include sites/*.site
exampleweb.site
<VirtualHost 0.0.0.0:80> RewriteEngine On RewriteRule ^(.*) https://%{HTTP_HOST}$1 [L,R] </VirtualHost>
exampleweb_ssl.site
SSLSessionCache shmcb:/run/httpd/sslcache(512000) SSLSessionCacheTimeout 300 SSLRandomSeed startup file:/dev/urandom 256 SSLRandomSeed connect builtin SSLCryptoDevice builtin SSLProtocol all -SSLv2 SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5 <VirtualHost 0.0.0.0:443> SSLEngine on SSLCertificateFile /var/www/ssl/server.crt SSLCertificateKeyFile /var/www/ssl/server.key </VirtualHost>
/var/www/cgi-bin-sso/.htaccess
#========== # .htaccess #========== SSLRequireSSL DirectoryIndex disabled AuthType Kerberos AuthName "Enter your MY.DESK username and password" KrbAuthRealms MY.DESK KrbVerifyKDC off #KrbMethodNegotiate off KrbMethodK5Passwd off KrbMethodNegotiate on Require valid-user
/var/www/cgi-bin-sso/view_sso_cgi_environment
#!/bin/sh echo "Content-Type: text/html" echo "" echo "<html>" echo "<head>" echo "<title>SSO CGI environment</title>" echo "</head>" echo "<body>" echo "<h1>SSO CGI environment</h1>" echo "<pre>" env | sed -e 's/&/\&/g' -e 's/</\</g' -e 's/>/\>/g' echo "</pre>" echo "</body>" echo "</html>"
Kerberos KDC
- Host: kerberos.my.desk
- Address: 192.168.254.4
- OS: CentOS release 6.6 (Final)
kdc.conf
[kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] MY.DESK = { #master_key_type = aes256-cts acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal } [root@kerberos ~]#
The principals
[root@kerberos ~]# kadmin.local Authenticating as principal root/admin@MY.DESK with password. kadmin.local: listprincs HTTP/exampleweb.my.desk@MY.DESK K/M@MY.DESK kadmin/admin@MY.DESK kadmin/changepw@MY.DESK kadmin/kerberos.my.desk@MY.DESK krbtgt/MY.DESK@MY.DESK master@MY.DESK kadmin.local: getprinc master Principal: master@MY.DESK Expiration date: [never] Last password change: Fri Feb 27 13:25:45 AEDT 2015 Password expiration date: [none] Maximum ticket life: 1 day 00:00:00 Maximum renewable life: 0 days 00:00:00 Last modified: Fri Feb 27 13:28:23 AEDT 2015 (root/admin@MY.DESK) Last successful authentication: [never] Last failed authentication: [never] Failed password attempts: 0 Number of keys: 6 Key: vno 1, aes256-cts-hmac-sha1-96, no salt Key: vno 1, aes128-cts-hmac-sha1-96, no salt Key: vno 1, des3-cbc-sha1, no salt Key: vno 1, arcfour-hmac, no salt Key: vno 1, des-hmac-sha1, no salt Key: vno 1, des-cbc-md5, no salt MKey: vno 1 Attributes: OK_AS_DELEGATE Policy: [none] kadmin.local: getprinc HTTP/exampleweb.my.desk Principal: HTTP/exampleweb.my.desk@MY.DESK Expiration date: [never] Last password change: Fri Feb 27 13:33:29 AEDT 2015 Password expiration date: [none] Maximum ticket life: 1 day 00:00:00 Maximum renewable life: 0 days 00:00:00 Last modified: Fri Feb 27 13:33:29 AEDT 2015 (root/admin@MY.DESK) Last successful authentication: [never] Last failed authentication: [never] Failed password attempts: 0 Number of keys: 6 Key: vno 2, aes256-cts-hmac-sha1-96, no salt Key: vno 2, aes128-cts-hmac-sha1-96, no salt Key: vno 2, des3-cbc-sha1, no salt Key: vno 2, arcfour-hmac, no salt Key: vno 2, des-hmac-sha1, no salt Key: vno 2, des-cbc-md5, no salt MKey: vno 1 Attributes: OK_AS_DELEGATE Policy: [none] kadmin.local: q [root@kerberos ~]#
Note that the OK_AS_DELEGATE attribute is set for both principals.
Mac OS X Yosemite desktop
- Host: macmini.my.desk
- Address: 192.168.254.3
- OS: Mac OS X Yosemite 10.10.2
krb5.conf
[libdefaults] default_realm = AD.UNSW.EDU.AU # allow_weak_crypto = true [realms] AD.UNSW.EDU.AU = { kdc = ad.unsw.edu.au # admin_server = kerbnfssrvr.my.desk } MY.DESK = { kdc = kerberos.my.desk } [domain_realm] .my.desk = MY.DESK .ad.unsw.edu.au = AD.UNSW.EDU.AU ad.unsw.edu.au = AD.UNSW.EDU.AU
Firefox
about:config → network.negotiate-auth.trusted-uris → .my.desk
After connecting...
$ klist Credentials cache: API:61376022-8DC9-44D4-A65A-EBA2AE885CE9 Principal: master@MY.DESK Issued Expires Principal Mar 5 12:25:07 2015 Mar 5 22:25:04 2015 krbtgt/MY.DESK@MY.DESK Mar 5 12:25:10 2015 Mar 5 22:25:04 2015 HTTP/exampleweb.my.desk@MY.DESK $
Safari
Version: 8.0.3
Works immediately. No changes required.