Kerberos auth with Apache/PHP

Robert Andresen Programming, Tutorials 5 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<br />
$ ntpdate domaincontroller-01.contoso.com<br />
$ 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<br />
mydomain.local<br />
type: kerberos<br />
realm-name: CONTOSO.COM<br />
domain-name: mydomain.local<br />
configured: kerberos-member<br />
server-software: active-directory<br />
client-software: sssd<br />
required-package: oddjob<br />
required-package: oddjob-mkhomedir<br />
required-package: sssd<br />
required-package: adcli<br />
required-package: samba-common<br />
login-formats: %U@mydomain.local<br />
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  ====================================</p>
<p>[ global ]<br />
#--authconfig--start-line--</p>
<p># Generated by authconfig on 2015/01/13 17:14:47<br />
# DO NOT EDIT THIS SECTION (delimited by --start-line--/--end-line--)<br />
# Any modification may be deleted or altered by authconfig in future</p>
<p>password server = domaincontroller-01.contoso.com<br />
security = domain<br />
idmap config * : range = 16777216-33554431<br />
kerberos method = secrets only<br />
winbind use default domain = false<br />
winbind offline logon = true</p>
<p>#--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<br />
Successfully mapped HTTP/webpage.contoso.com to &lt;username&gt;.<br />
Password succesfully set!<br />
Key created.<br />
Key created.<br />
Key created.<br />
Key created.<br />
Key created.<br />
Output keytab to webpage.HTTP.keytab:<br />
Keytab version: 0x502<br />
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<br />
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]<br />
default = /var/log/krb5libs.log<br />
kdc = /var/log/krb5kdc.log<br />
admin_server = /var/log/kadmind.log</p>
<p>[libdefaults]<br />
default_realm = CONTOSO.COM<br />
dns_lookup_realm = true<br />
dns_lookup_kdc = true<br />
ticket_lifetime = 24h<br />
forwardable = yes</p>
<p>[realms]<br />
CONTOSO.COM = {<br />
kdc = domaincontroller-01.contoso.com:88<br />
kdc = domaincontroller-02.contoso.com:88<br />
kdc = domaincontroller-03.contoso.com:88<br />
admin_server = domaincontroller-01.contoso.com:749<br />
default_domain = contoso.com<br />
}</p>
<p>[domain_realm]<br />
webpage.contoso.com = CONTOSO.COM<br />
.contoso.com = CONTOSO.COM<br />
contoso.com = CONTOSO.COM</p>
<p>[appdefaults]<br />
pam = {<br />
debug = true<br />
ticket_lifetime = 36000<br />
renew_lifetime = 36000<br />
forwardable = true<br />
krb4_convert = false<br />
}

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<br />
AuthName "Kerberos Login"<br />
KrbServiceName HTTP<br />
KrbMethodNegotiate On<br />
KrbMethodK5Passwd Off<br />
KrbSaveCredentials Off<br />
KrbVerifyKDC On<br />
KrbAuthRealms CONTOSO.COM<br />
Krb5KeyTab /etc/httpd/conf/webpage.HTTP.keytab<br />
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<br />
echo "&lt;h2&gt;Kerberos Auth&lt;/h2&gt;";<br />
echo "Auth type: " . $_SERVER['AUTH_TYPE'] . "&lt;br /&gt;";<br />
echo "Remote user: " . $_SERVER['REMOTE_USER'] . "&lt;br /&gt;";<br />
?&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;<br />
AllowOverride <span style="color: #ff0000;">All</span><br />
# Allow open access:<br />
Require all granted<br />
&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.

#<br />
# LogLevel: Control the number of messages logged to the error_log.<br />
# Possible values include: debug, info, notice, warn, error, crit,<br />
# alert, emerg.<br />
#<br />
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<br />
[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<br />
[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<br />
[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<br />
[Wed Jan 14 10:45:52 2015] [debug] src/mod_auth_kerb.c(1286): [client 172.27.10.101] Verification returned code 0<br />
[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<br />
[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<br />
[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<br />
[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