My goal is to have Apache authenticate authenticate against AD, without prompting for a username and password, using Kerberos. It currently always shows "401 Unauthorized", and appears to be not trying Kerberos. I can't find any error logs, and can only find one kinit
command that clearly doesn't work and gives an error - that error shows up in WireShark as:
Linux sends AS-REQ
Windows replies KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
Clue or red herring?
Setup / background details
Windows Server 2008 R2 SP1, with Active Directory ("winserver").
CentOS 6.5 ("centos").
Configure hostname and DNS and add A and PTR entries in Windows DNS server. Name resolution appears OK.
Create
/etc/krb5.conf
and/etc/samba/smb.conf
usingauthconfig-tui
and tweak them.
krb5.conf
`/etc/krb5.conf`
[libdefaults]
default_realm = SITE.EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
SITE.EXAMPLE.COM = {
kdc = winserver.site.example.com
admin_server = winserver.site.example.com
}
[domain_realm]
site.example.com = SITE.EXAMPLE.COM
and Samba
`/etc/samba/smb.conf` includes
workgroup = SITE
password server = winserver
realm = SITE.EXAMPLE.COM
security = ads
kerberos method = system keytab
winbind use default domain = true
From here, Kerberos setup steps:
net ads join createupn=HOST/[email protected] -k -U administrator
asks me for a Windows password, and accepts it. It joins the domain (creates a computer object in AD).net ads testjoin
reports "join is OK".net ads keytab create -k -U administrator
creates/etc/krb5.keytab
and fills it withHOST/centos....
permutations.net ads keytab add HTTP -k -t /etc/krb5.keytab -U administrator
addsHTTP/centos.site.example.com
entries to the keytab.klist -ke
shows a lot of SPN combinations, includingHTTP/[email protected]
and appears to match the KVNO with Windows' msDS-KeyVersionNumber attribute on the server object.
At this point, I can connect by SSH using PuTTY and be automagically logged in with SSO with no password prompt. I can connect by SSH and force a password prompt, use a Windows username and password and log in. After logging in using a Windows account, I can kinit
and then klist
see Kerberos tickets. I can use wbinfo -u
and wbinfo -g
and net ads search
to query AD and get results.
Everything looks good. Let's move on to Apache:
chgrp apache /etc/krb5.keytab
chmod ugo+r /etc/krb5.keytab
yum install mod_auth_kerb
Edit
/etc/httpd/conf/httpd.conf
and add:
httpd.conf
LoadModule auth_kerb_module /usr/lib64/httpd/modules/mod_auth_kerb.so
AuthName "Kerberos Authentication"
AuthType Kerberos
Krb5Keytab /etc/krb5.keytab
KrbAuthRealms SITE.EXAMPLE.COM
KrbMethodNegotiate on
KrbMethodK5Passwd off
KrbServiceName Any
In Internet Explorer, "Local Intranet sites" includes http://*.site.example.com
and is set to 'automatic logon only in intranet zone'. Automatic login works for other (IIS based) websites in the office using these settings. In FireFox, about:config has network.negotiate-auth.trusted-uris; .site.example.com
.
In IE, FireFox or Chrome, I visit the site with the FQDN, get 401 Unauthorized
. It doesn't appear that Kerberos is even being tried.
I can't find anything in the Linux log files, /var/log/httpd/error_log or access_log /var/log/secure or /var/log/audit/audit.log to show anything going wrong.
Trying to find things to test, the only thing I can find to create a clear and relevant-seeming error is the command:
$ kinit -k -t /etc/krb5.keytab HTTP/centos.site.example.com
kinit: Client not found in Kerberos database while getting initial credentials
I don't know exactly what it's doing, but if I WireShark it:
Linux sends AS-REQ to Windows with content
cname name-string 2 items
KerberosString: HTTP
KerberosString: centosserver.site.example.com
realm: SITE.EXAMPLE.COM
Windows replies KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
error-code eRR-C-PRINCIPAL-UNKNOWN (6)
On Windows, if I use setspn -L centos
it shows Registered Principal Names include HTTP/centos.site.example.com.
On my Windows desktop client, if I klist get HTTP/centos.site.example.com
then I get a ticket showing up as Client: [email protected], Server: HTTP/centos.site.example.com.
It feels a bit like http://support.microsoft.com/kb/951191 - but that only applies to Windows Server 2008 original, pre Service Pack 2. This is Windows Server 2008 R2 Service Pack 1. I've tried pointing it to another domain controller, but that's also running the same Windows Server version and responds the same way.
On the Linux side: I've been working with CentOS 6.5 (Samba 3.x, Kerberos 5.0), but I've also fresh installed CentOS 7 (Samba 4.x and Kerberos 5.1) and tried the same setup and got the same results from kinit. I haven't tried Apache on CentOS 7.
Passwordless logins for SSH work. Login authentication against AD works with kinit. Kerberos authentication doesn't work in Apache, it doesn't even seem to try in Apache, or log any errors. What am I missing, why doesn't it try Kerberos authentication? What can I test or do to make it log more?
And the only thing I can clearly make fail is that command ^ which I found on the internet, but I don't know exactly what it's testing. What is it doing and why doesn't it work, when apparently, my desktop can query AD for the same service principal and get an answer?
[Edit update]
I followed natxo asenjo's answer to 'do it differently', and now I have a setup that works. I also accept that having different usernames in AD for each service, and then creating separate keytabs, is reasonable (e.g. if Apache is compromised and the HTTP/ keytab it can read is compromised, the HOST/ keytab is still safe for a bit).
However I have no answer to why the Kerberos principal lookup to windows was failing with my original approach. Which is frustrating, given that guides like http://requesttracker.wikia.com/wiki/Kerberos_SSO_with_Active_Directory_Integration and http://wiki.gentoo.org/wiki/Kerberos_Windows_Interoperability put several principals in one keytab tied to the computer account, using the Samba net ads commands, and (presumably) get a working setup out of it.
I have used the instructions on http://www.grolmsnet.de/kerbtut/ many times because they work. For the record, you do not need to join the linux host to the AD domain, it's ok to do it but not necessary.
First of all, ensure you can kinit from the centos host to your AD realm. You can use your normal user credentials like this:
(kinit is part of the krb5-workstation package in centos, by the way)
Enter your password and no news is good news. Run klist and you should see a kerberos ticket there as your AD username. If this step is not successful go back and fix your krb5.conf until it is.
Get rid of that ticket with kdestroy.
Once that works you can create a user account in AD. Ensure that it does not have to change its password and that the password does not expire.
Then we bind the service principal name (spn) HTTP/host.adrealm.tld to that useraccount using setspn.exe on a windows hosts with the management tools or in a domain controller as an admin or account with sufficient privileges:
Now we can generate the keytab for this object using ktpass.exe (still in the windows management host or domain controller):
Transport that file to the centos host and place it with 640 permissions (root:apache) in /etc/httpd/conf.d/ . If selinux is enabled, run restorecon -rv /etc to eventually fix selinux contexts there.
You can verify the keytab file with:
And you could even go one step further by using it to log on:
In your dns infrastructure (probably in AD dns as well), create an A host.realm.tld pointing to the centos host (if you use samba to join the host it should have created it for you, ensure it is correct).
Ensure your centos hosts has the mod_auth_kerb installed.
Whant that is in place you edit one of the apache conf files of your (virtual) hosts for apache.
In this case, let's protect the folder http://host.adrealm.tld/topsecret:
Create the topsecret folder in the filesystem of the centos host. Set a couple of dummy files in there. If you run with selinux enable, ensure that folder has the right security context for apache (if the folder is in /var/www/html it should be righ an running restorecon -rv /var/www/html will eventually fix any selinux problems).
Verify the apache2 syntax passes:
If you get 'Syntax OK' with warnings about not being able to reliably determine the host fqdn, then you are good to go (you can fix that later if you want, it is not critical). Reload apache:
Verify your local firewall allows httpd connexxions.
This should be it. Now you need to configure the clients. If you already have webservers with 'Windows Authentication' in your network then you are set, go to the topsecret url and if you have a valid kerberos ticket you should see the files, otherwise you will get access denied.