HTTP SSO with Kerberos

on Ubuntu xenial with Apache 2.4

It does not matter how much services you put in place. To validate this flavor of SSO, one service is enough, since there is no proxy/entry-point layer as for CAS or SAML. The tickets are initiated onto the underlying system. So if you do not get prompted for a password when calling one web service, it will most probably mean that the same will happen for any other Kerberos enabled web services.


samba-tool dns add dc1.example.local example.local ubuntu63 A x.x.x.63
samba-tool dns add dc1.example.local example.local ubuntu64 A x.x.x.64

samba-tool dns zonecreate dc1.example.local
samba-tool dns add dc1.example.local 1 PTR dc1.example.local
samba-tool dns add dc1.example.local 63 PTR ubuntu63.example.local
samba-tool dns add dc1.example.local 64 PTR ubuntu64.example.local


host lenovo.example.local dc1.example.local
host ubuntu63.example.local dc1.example.local
host ubuntu64.example.local dc1.example.local

host x.x.x.1 dc1.example.local
host x.x.x.63 dc1.example.local
host x.x.x.64 dc1.example.local

in case you need to undo some mistake,

#samba-tool dns delete dc1.example.local x PTR ubuntuxx.example.local.


The Apache servers can be left out of the AD domain. As said in the introduction, what matters is rather the clients.

systemctl stop smbd  
systemctl stop nmbd
systemctl stop winbind
systemctl disable smbd  
systemctl disable nmbd
systemctl disable winbind


Each network service which requires a different host name will need its own set of Kerberos keys. This complicates virtual hosting and clusters.

on dc1

samba-tool user create --random-password apache63
samba-tool spn add HTTP/ubuntu63.example.local apache63
samba-tool domain exportkeytab /root/apache63.keytab --principal=HTTP/ubuntu63.example.local@EXAMPLE.LOCAL

ssh ubuntu63 'apt install apache2 libapache2-mod-auth-kerb'
scp /root/apache63.keytab ubuntu63:/etc/apache2/apache63.keytab

on ubuntu63

ps aux | grep ^www
ls -lhF /etc/apache2/apache63.keytab #root/root/600
chgrp www-data /etc/apache2/apache63.keytab 
chmod g+r /etc/apache2/apache63.keytab

echo '<p>auth success on ubuntu63' > /var/www/html/login.html

cp -pi /etc/apache2/apache2.conf /etc/apache2/apache2.conf.dist
vi /etc/apache2/apache2.conf

<location "/login.html">
       AuthType Kerberos
       AuthName "Network Login"
       KrbMethodNegotiate On
       KrbMethodK5Passwd On
       KrbAuthRealms EXAMPLE.LOCAL
       require valid-user
       Krb5KeyTab /etc/apache2/apache63.keytab
       KrbLocalUserMapping On

systemctl restart apache2 

as e.g. EXAMPLE\user1 from a graphical desktop station

host ubuntu63.example.local

nmap -sU -p 88 dc1.example.local
kinit user1



In case you wanna try without KRB,



==> you get the auth prompt and you need to provide user name (short form works).


Client-Side Setup: silent auth with Firefox

This setup is heavily based on the Samba4/AD DC and Samba4/AD member guides. So the Kerberos client setup is already done on the validating workstation with the Firefox front-end. We also tried to run firefox as another user while initiating a ticket for user1 and as a result, we got the authentication prompt instead of being authenticated. We did not try to hack it with a system user having the same name of a Kerberos user (assuming the host is NOT a domain member) – maybe this could have worked out.


network.negotiate-auth.trusted-uris;http://ubuntu63, http://ubuntu64, .example.local



If getting this error while setting up a new DNS record,


==> make sure you called the DC name accordingly e.g. dc1.example.local versus host.example.local.

If getting this error when trying to access the protected web page,

[auth_kerb:error] ... gss_acquire_cred() failed: Unspecified GSS failure.  Minor code may provide more information (, No key table entry found matching HTTP/ubuntu64@)

==> re-create the keytab with FQDN instead of short form.

And if getting this one,

[auth_kerb:error] ... gss_acquire_cred() failed: Unspecified GSS failure.  Minor code may provide more information (, No key table entry found matching HTTP/ubuntu63.example.local@)

==> double-check the DNS and reverse-DNS entries, seek and destroy possible duplicates.