Kerberos auth with Apache/PHP

Robert AndresenProgramming, Tutorials5 Comments

We have a portal/intranet-webpage at my work, running with Apache, PHP and MySQL. In 2011, a colleague and me sat 16 hours (without a break) and configured kerberos authentication with the Linux webserver.

Now in 2015 we needed kerberos with a new webserver. We did write a doc back in 2011, but when you sit for 16 hours – the doc can be a little short of all the things we actually did. The configuration took about 8 hours this time, and now I’m updating the doc and blogging it here.

 

Why

When users log in on their Windows computers, they can access the Intranet-webpage without having to authenticate themselves one more time.

 

Prerequisite:

  • A working domain with basic knowledge of it.
  • A working Linux webserver with Apache and PHP

My setup:

  • CentOS 7 (With Apache 2 and PHP 5.4)
  • Domain controller on Windows server 2008 R2.

 

Before you start:

The commands and images are masked from all that are related to my work-infrastructure. Remember to change it matching your own network and domain. Contoso.com is the example domain and http://website.contoso.com is the website DNS. Use the images for illustration for what the output should look like.

$vi   is the editor used in this guide. Use the editor of your own choice. To edit a file in vi, enter a-key when you are in the file and start editing. When your done, press esc and just write :wq (write quit) to save (or :q to quit).

I wrote this guide as I configured kerberos – which means I didn’t necessary follow the steps below in the same order. I got some error messages that probably was because of the last kerberos configuration.

I recommend scrolling through this guide and the sources at the bottom BEFORE you start, to get a better view of what you are going to do. If your not at work, go get some beers, because this could take some time 🙂

As kerberos already was in use on other services in my case, I am not sure if any changes need to be made at the domain-structure.

 

1. Turn OFF SELinux and firewall

Do this under setup to prevent any interupt, and remember to set them back when you’re done!

$ setenforce 0

$ systemctl stop firewalld

 

2. Install mod_auth_kerb

You need the mod_auth_kerb module for apache, so apache can handle the kerberos tickets.

$ yum install mod_auth_kerb

$ systemctl restart httpd.service

 

3. Join the Linux server into the domain

Source: http://www.hexblot.com/blog/centos-7-active-directory-and-samba

Install required packages:

$ yum install realmd samba samba-common oddjob oddjob-mkhomedir sssd ntpdate ntp

 

3.1 Sync time with the domain

This is not required, but the time have to match the domain controller in order to authenticate users.

$ systemctl enable ntpd.service
$ ntpdate domaincontroller-01.contoso.com
$ systemctl start ntpd.service

 

3.2 Join the domain

$ realm join --user=adminuser@contoso.com contoso.com

 

List the domain-data for the server to check if it works. This looked fine to me the first time, but the computer object did not show in AD. So I had to leave ($realm leave…) the domain and join it one more time for some reason.

$ realm list

$ realm list
mydomain.local
type: kerberos
realm-name: CONTOSO.COM
domain-name: mydomain.local
configured: kerberos-member
server-software: active-directory
client-software: sssd
required-package: oddjob
required-package: oddjob-mkhomedir
required-package: sssd
required-package: adcli
required-package: samba-common
login-formats: %U@mydomain.local
login-policy: allow-realm-logins

 

3.3 Samba config

$ vi /etc/samba/smb.conf

The config should already be something like this. This is my config-file:

#======================= Global Settings  ====================================

[ global ]
#--authconfig--start-line--

# Generated by authconfig on 2015/01/13 17:14:47
# DO NOT EDIT THIS SECTION (delimited by --start-line--/--end-line--)
# Any modification may be deleted or altered by authconfig in future

password server = domaincontroller-01.contoso.com
security = domain
idmap config * : range = 16777216-33554431
kerberos method = secrets only
winbind use default domain = false
winbind offline logon = true

#--authconfig--end-line--

 

4. Computerobject in AD

Open AD and check that the computer object is created.

View the properties for the computer object and go to Delegation tab – make sure that “Trust this computer for delegation to any service (Kerberos only)” is checked.

kerberos_computerobject_delegation

 

5. Create a service user

Create a service user in the domain.

After the user is created and you run the ktpass in the next step – it would show a new tab named “Delegation” in the user-properties.

kerberos_mgmt_account

 

6. Generate keytab file

Keytab-file need be created in CMD on a server in the domain. The <USERNAME> should be the service user you created in last step.

Notice: The user will store a key version number. In my case, I created the keytab file on the same user as last time, meaning that the old kerberos setup stopped working.

ktpass -princ HTTP/contoso.com@CONTOSO.COM -mapuser CONTOSO\&lt;USERNAME&gt; -crypto all -ptype KRB5_NT_PRINCIPAL -pass &lt;PASSWORD&gt; -out webpage.HTTP.keytab

 

 

Output:

Targeting domain controller: domaincontroller-01.contoso.com
Successfully mapped HTTP/webpage.contoso.com to &lt;username&gt;.
Password succesfully set!
Key created.
Key created.
Key created.
Key created.
Key created.
Output keytab to webpage.HTTP.keytab:
Keytab version: 0x502
keysize 87 HTTP/webpage.contoso.com@CONTOSO.COM ptype 1 (KRB5_NT_PRINCIPAL) vno 26 etype 0x1 (DES-CBC-CRC) keylength 8 (0x404398) keysize 87 HTTP/webpage.contoso.com@CONTOSO.COM ptype 1 (KRB5_NT_PRINCIPAL) vno 26 etype 0x3 (DES-CBC-MD5) keylength 8 (04043 98) keysize 95 HTTP/webpage.contoso.com@CONTOSO.COM ptype 1 (KRB5_NT_PRINCIPAL) vno 26 etype 0x17 (RC4-HMAC) keylength 16 (0x72827cb052e8) keysize 111 HTTP/webpage.contoso.com@CONTOSO.COM ptype 1 (KRB5_NT_PRINCIPAL) vno 26 etype 0x12 (AES256-SHA1) keylength 32 (0x75f60e)keysize 95 HTTP/webpage.contoso.com@CONTOSO.COM ptype 1(KRB5_NT_PRINCIPAL) vno 26 etype 0x11 (AES128-SHA1) keylength 16 (0xf4e248)

kerberos_ktpass

 

Open the service-user properties. Go to the Delegation tab and make sure the “Trust this user for delegation to any service (Kerberos only) is checked.

kerberos_mgmt_account_delegation

 

7. Copy keytab file to the webserver

Use WinSCP, mount a NFS or something to copy the generated keytab file to /etc/httpd/conf on the webserver.

7.1 Change the user-rights and group on the keytab-file

chgrp apache webpage.HTTP.keytab
chmod 740 webpage.HTTP.keytab

 

8. Setspn

Open powershell on a domain controller and add set spn:

PS C:\Users\admin&gt; setspn -s HTTP/webpage.contoso.com &lt;SERVICE USER&gt;

kerberos_setspn

In my case the domain webpage.contoso.com existed from before, so I got a duplicate message. I had to write “PS C:\Users\admin> setspn -D http/intranett.contoso.com <OLD SERVICE USER>” to delete it.

 

9. Edit /etc/krb5.conf

[logging]
default = /var/log/krb5libs.log
kdc = /var/log/krb5kdc.log
admin_server = /var/log/kadmind.log

[libdefaults]
default_realm = CONTOSO.COM
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 24h
forwardable = yes

[realms]
CONTOSO.COM = {
kdc = domaincontroller-01.contoso.com:88
kdc = domaincontroller-02.contoso.com:88
kdc = domaincontroller-03.contoso.com:88
admin_server = domaincontroller-01.contoso.com:749
default_domain = contoso.com
}

[domain_realm]
webpage.contoso.com = CONTOSO.COM
.contoso.com = CONTOSO.COM
contoso.com = CONTOSO.COM

[appdefaults]
pam = {
debug = true
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}

10. Create a auth folder on your webserver for testing

$ mkdir /var/www/html/auth

Than create a .htaccess file in the folder where you want to authenticate the user. You can also add these parameters at the virtual host config if you want.

$ vi /var/www/html/auth/.htaccess

Insert the following config

 AuthType Kerberos
AuthName "Kerberos Login"
KrbServiceName HTTP
KrbMethodNegotiate On
KrbMethodK5Passwd Off
KrbSaveCredentials Off
KrbVerifyKDC On
KrbAuthRealms CONTOSO.COM
Krb5KeyTab /etc/httpd/conf/webpage.HTTP.keytab
require valid-user

Remember to check if Apache loads .htaccess files. See 14.1.

11. Test the kerberos authentication

Create a test folder called auth in www-root.

[root@S1000-2WM-0020 conf]# mkdir /var/www/html/auth

Create a index.php in the folder:

[root@S1000-2WM-0020 conf]# vi /var/www/html/auth/index.php

Add the following code to the index.php file:

&lt;?php
echo "&lt;h2&gt;Kerberos Auth&lt;/h2&gt;";
echo "Auth type: " . $_SERVER['AUTH_TYPE'] . "&lt;br /&gt;";
echo "Remote user: " . $_SERVER['REMOTE_USER'] . "&lt;br /&gt;";
?&gt;

12. Test website

The page should look like this:

kerberos_chrome_auth_success

 

13. Turn ON SELinux and firewall

$ setenforce 1

$ systemctl start firewalld

 

14. Troubleshoot

14.1 Enable .htaccess to be read in Apache

If .htaccess isn’t loaded, you need to edit /etc/httpd/httpd.conf and set AllowOverride All.

&lt;Directory "/var/www"&gt;
AllowOverride <span style="color: #ff0000;">All</span>
# Allow open access:
Require all granted
&lt;/Directory&gt;

14.2 Set apache LogLevel to debug

To get all possible messages for debugging, it can be useful to set apache LogLevel to debug. Edit the /etc/httpd/httpd.conf file.

#
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
LogLevel debug

14.3 Test keytab file and kerberos authentication

You can test the kerberos authentication from the terminal. First you need to install the kerberos-workstation tools.

$ yum install krb5-workstation.x86_64

Test the keytab-file

$ kinit -k -t /etc/httpd/conf/webpage.HTTP.keytab HTTP/webpage.contoso.com

Test user login:

$ kinit &lt;a domain username&gt;@CONTOSO.COM

Check kerberos tickets:

$ klist

Delete the kerberos ticket:

$ kdestroy

 

14.4 View the apache logs

$ tail /var/log/httpd/error_log -n 15

A successfully kerberos-login should look like this in the log.
You may want to set apache LogLevel to debug (see 14.2).

[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1496): [client 172.27.10.101] kerb_authenticate_user entered with user (NULL) and auth_type Kerberos
[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1496): [client 172.27.10.101] kerb_authenticate_user entered with user (NULL) and auth_type Kerberos
[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1151): [client 172.27.10.101] Acquiring creds for HTTP@webpage.contoso.com
[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1270): [client 172.27.10.101] Verifying client data using KRB5 GSS-API
[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1286): [client 172.27.10.101] Verification returned code 0
[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1304): [client 172.27.10.101] GSS-API token of length 161 bytes will be sent back
[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1352): [client 172.27.10.101] set cached name &lt;domainuser&gt;@CONTOSO.COM for connection
[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1496): [client 172.27.10.101] kerb_authenticate_user entered with user (NULL) and auth_type Kerberos
[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1527): [client 172.27.10.101] using cached name &lt;domainuser&gt;@CONTOSO.COM

A list of the error messages and description for each one can be viewed here: http://sammoffatt.com.au/…table_entry_not_found_while_getting_initial_credentials

 

Sources

Some of the sources refers to compiling the module for apache. I ONLY installed the mod_kerb_auth, and did not compile anything.

Update 2016-05-02: Found another howto guide to set up kerberos http://wiki.openiam.com/display/IAMSUITEV3/Kerberos+Authentication+When+Using+the+Reverse+Proxy

  • planetfour

    Thanks for sharing. I did a similar thing with ubuntu and Joomla some year ago. Just as you I can not really remember what I did. This time I will do the same but to a wordpress site where the users are connected to our AD via ldap.This part works fine. However I am confused if setting it up as you describe will log me in automaticly to wordpress or if I will need some other plugin as well. What intranet site were you using in your example?

    • Robert Andresen

      Hi. The intranet page i’m using kerberos auth on, is developed from scratch. So I basically use step 10 and 11 to auth the users and create a PHP login/auth-session from there.

      I haven’t used kerberos with wordpress before, but if you can’t find a plugin – you probably need to write your own – Where you set the WordPress login session somehow, with the $_SERVER parameters.

  • Pingback: Apache SSO over AD | Le shell à la ligne...()

  • bisigan

    very interesting tutorial but im confused you use samba and apache in the same OS or in diferent?

    • Robert Andresen

      In the same OS for this setup 🙂