4

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").
  1. Configure hostname and DNS and add A and PTR entries in Windows DNS server. Name resolution appears OK.

  2. Create /etc/krb5.conf and /etc/samba/smb.conf using authconfig-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:

  1. net ads join createupn=HOST/centos.site.example.com@SITE.EXAMPLE.COM -k -U administrator asks me for a Windows password, and accepts it. It joins the domain (creates a computer object in AD).

  2. net ads testjoin reports "join is OK".

  3. net ads keytab create -k -U administrator creates /etc/krb5.keytab and fills it with HOST/centos.... permutations.

  4. net ads keytab add HTTP -k -t /etc/krb5.keytab -U administrator adds HTTP/centos.site.example.com entries to the keytab. klist -ke shows a lot of SPN combinations, including HTTP/centos.site.example.com@SITE.EXAMPLE.COM 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:

  1. chgrp apache /etc/krb5.keytab

  2. chmod ugo+r /etc/krb5.keytab

  3. yum install mod_auth_kerb

  4. 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: myusername@SITE.EXAMPLE.COM, 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.

3

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 yourusername@ADREALM.TLD

(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:

setspn -A HTTP/host.adrealm.tld username [enter]
Registering ServicePrincipalNames for CN=username,OU=service_accounts,dc=adrealm,DC=tld
        HTTP/host.adrealm.tld
Updated object

Now we can generate the keytab for this object using ktpass.exe (still in the windows management host or domain controller):

ktpass -princ HTTP/host.adrealm.tld@ADREALM.TLD -pass xxxxx -mapuser username -Ptype KRB5_NT_PRINCIPAL -out host_adrealm_tld.keytab [enter]
Targeting domain controller: DCname.Adrealm.tld
Successfully mapped HTTP/host.adrealm.tld to username.
Password succesfully set!
Key created.
Output keytab to host_adrealm_tld.keytab:
Keytab version: 0x502
keysize 75 HTTP/host.adrealm.tldl@ADREALM.TLD ptype 1 (KRB5_NT_PRINCIPAL)
vno 3 etype 0x17 (RC4-HMAC) keylength 16 (0x037da0f7493b97966e4a19636304064d)

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:

$ klist -k -t host_adrealm_tld.keytab 
Keytab name: FILE:host_adrealm_tld.keytab
KVNO Timestamp         Principal
---- ----------------- --------------------------------------------------------
   3 01/01/70 01:00:00 HTTP/host.adrealm.tld@ADREALM.TLD

And you could even go one step further by using it to log on:

# kinit -k -t host_adrealm_tld.keytab -p HTTP/host.adrealm.tld@ADREALM.TLD
# klist 
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: HTTP/host.adrealm.tld@ADREALM.TLD

Valid starting     Expires            Service principal
11/04/14 21:45:41  11/05/14 07:45:41  krbtgt/ADREALM.TLD@ADREALM.TLD
    renew until 11/05/14 21:45:41

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:

Alias /topsecret/ "/path/to/topsecret/"

<Directory "/path/to/topsecret/">

    AuthType  Kerberos
    KrbAuthRealms YOURAD.TLD
    KrbServiceName HTTP
    Krb5Keytab /etc/httpd/conf.d/host_adrealm_tld.keytab
    KrbMethodNegotiate on
    KrbMethodK5Passwd off
    require valid-user

</Directory>

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:

apachectl -t

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:

apachectl graceful 

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.

  • I'm not sure what to do with your answer; it's detailed and I appreciate that, but I have found the grolmsnet.de guide before and I'm not willing to create a dummy user account in AD and manually deal with passwords and manually specify encryption modes. It's a bodge, a workaround - I think for the problem where ktpass in Windows generates a keytab with a mismatched KVNO field compared to the server's AD object, and net ads keytab commands fix that now. You haven't really answered either of my problems, except saying "do it completely differently". – TessellatingHeckler Nov 4 '14 at 21:19
  • I can kinit with my username, I can verify the keytab has correct looking principals in it with kinit -ke and the suggestion to 'even go one step further by using it to log on` is the command that doesn't work for me and I would love to know what's going wrong with it. – TessellatingHeckler Nov 4 '14 at 21:20
  • I'sorry you find it a bodge or a workaround. It is not. Separating the host keytab from the service principal is a must, and you are mixing them. If MS provided a native way of joining hosts to their kerberos realm, we would not have to do all this. But they don't and their only supported way of getting a keytab is using ktpass.exe. I would not call it a workaround but their 'best practices'. As to why you cannot verify the keytab, well, you are missing the -p switch to kinit – natxo asenjo Nov 4 '14 at 21:30
  • 1
    What am I mixing, exactly? There are no virtualhosts or other name for the website, the only hostname in the keytab is the CentOS server's FQDN, for the principals HOST/ and HTTP/. Here (requesttracker.wikia.com/wiki/… and wiki.gentoo.org/wiki/Kerberos_Windows_Interoperability are two guides which use 'net ads keytab add HTTP' and don't use ktpass. i.e. it should work even if unsupported by Microsoft). The -p switch (upper or lowercase) makes no difference to the kinit command. – TessellatingHeckler Nov 4 '14 at 21:57
  • 1
    you are mixing the keytabs for 2 spns: HOST and HTTP. Security is a layered cake. If an attacker grabbed that keytab, he/she would have 2 principals to play with. As to the kvno and ktpass: how often do you think I create the keytab? I have truly never had this problem (except when we recreate the keytabs every now and then for security purposes, but then it is us who do it). Anywawys, nowadays most folks use realmd or msktutil to join hosts to AD realms instead of samba. You could try web.mit.edu/kerberos/krb5-devel/doc/admin/troubleshoot.html to debug the kinit command. – natxo asenjo Nov 4 '14 at 22:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.