Active Directory Kerberos authentication for Apache web server

[ AD  authentication  Apache  Linux  ]

11 Sep 2018

UPDATED on 23 October 2018: There is a follow-up post for this article with some additional notes, which came as a result of an email conversation with one reader, who also struggled with the quirks of Kerberos+AD+Linux+Apache combination but managed to make it work after all.

I was recently involved in configuration of Kerberos authentication for a newly deployed Apache web site, using mod_auth_kerb module. We have an Active Directory environment with the largest part of our users working on Windows 7+ computers, but the Apache web site was supposed to be running on a Linux host. I configured an Apache web site hosted on a Linux box to use Kerberos to transparently authenticate AD users connecting from Windows computers (IE and Chrome browsers). I also enabled support for both RC4 and AES256 Kerberos encryption methods, and this was the trickiest part of all. While we still support the older RC4 encryption for Kerberos in our environment because we have some legacy systems not capable of using AES encryption, it is a very good idea to ensure that all new installations support AES by default as its more secure. You can find the following statement in the official IETF description of the Microsoft implementation of the RC4 encryption for Kerberos:
It is thus RECOMMENDED not to use the RC4 encryption types defined in this document if alternative stronger encryption types, such as aes256-cts-hmac-sha1-96 [RFC3962], are available.

Overview of configuration steps

There are many Internet resources describing the configuration process for Apache + mod_auth_kerb + AD - just google for “Apache mod_auth_kerb AD” and you get tons of step-by-step instructions and guides. But in the end, I had to gather pieces of information from many different source, because there was not one guide which explained all Kerberos machinery, options and required configuration actions in sufficient details in one place. The most useful and comprehensive resources that I was able to find are listed in the end of this document.

The tested configuration process looks like that:

  1. Prepare and write down the crucial configuration parameters which you will use in the next steps:
    • Apache web site FQDN (more details on this below)
    • Active Directory account to be used as the service account (service identity) for this web site
    • FQDNs of at least two AD domain controllers that you are going to use as the KDCs for the Linux box
    • The DNS name of you AD domain
  2. Prepare Linux box:
    • Install krb5-user package - binaries required to configure the Linux server as a “service” per Kerberos protocol terminology
    • Install Apache 2
    • Install mod_auth_kerb Apache module
  3. Run Windows tool ktpass on AD domain controller to generate and output to the console two secret keys (for AES256 and RC4 encryption methods, respectively) associated with the service account specially created in the AD to be used as the identity of the web server. At this step I deviate from most of the instructions and manuals published in the Internet, because I discard the keytab file generated by ktpass and just take the values for the secret key and key serial number (vno) that I copy from the console output of this command and use them to create required entries in the keytab file manually on the Linux box. The reason why I make it so complicated is because I found no way to generate the keytab file directly using the ktpass tool for AES cipher as either the secret key was wrong because of the salt or the key was valid but the SPN was wrong.
  4. Run Windows tool setspn on AD domain controller to configure proper SPN attribute (Kerberos Service Principal Name) in the properties of the service account AD object.
  5. Create a DNS record for the public FQDN of the web server (the one entered in the browser address bar). If you have a single web site on your web server then the simplest option is to make sure that the public URL of your site is the same as the FQDN of the server configured in the /etc/hosts configuration file, and create an A DNS record for this FQDN pointing directly to the server’s IP address. However, if you want to host two or more web sites on the save web server with different host headers, then the situation becomes complicated and you will have to properly configure DNS CNAME records and keytab file. One option in this case is to use the same service account identity for all web sites hosted on the web server, configure keytab file for the server’s own FQDN configured in the /etc/hosts file and create CNAME DNS aliases for your web sited pointing to the server’s FQDN. The browsers will perform DNS name canonization and will request Kerberos service tickets not for the CNAME addresses of the web sites, but for the server’s own FQDN.
  6. On the Linux box, use ktutil tool (part of the krb5-user package) to create a new empty keytab file and then use its addent subcommand to add two entries for AES256 and RC4 encryption schemes using the secret keys output to the console by ktpass tool at step 3.
  7. Configure host-wide Kerberos parameters for the krb5-user package by editing configuration file /etc/krb5.conf
  8. Configure mod_auth_kerb Apache module parameters by editing the Apache web site configuration file (i.e., /ect/apache2/sites-enabled/000-default.conf) and adding Kerberos specific entries under the VirtualHost section.
  9. Optionally enable the fall-back mechanism available in the mod_auth_kerb which allows clients which do not support Kerberos to use Basic HTTP authentication scheme instead (SECURITY WARNING! Do not enable this option unless you also enable AND force SSL/TLS for your web site.)
  10. Make sure that the browsers on Windows client computers are configured to start Kerberos authentication with your web site automatically and send the cached Windows credentials (check Internet Explorer “Local intranet” zone settings) 1.

Example configuration step-by-step

The example below has been tested on a freshly installed Ubuntu system in a mixed Windows 2008R2/2012R2 AD domain controllers environments. Change the URLs, accounts and domain names to match your own settings and it should probably work for you as well.
As we remember, from the Kerberos protocol point of view, there are three computers participating in the authentication process: KDC (domain controller), service (Apache web server) and client (Windows computer accessing the web site). In the table below, the second column specifies the computer where the configuration commands and actions for the current step must be executed. The third columns specifies whether this step is a command that you need to execute or some other type of action that you must carry out. Run all commands exactly as given in the table in Windows CMD or Linux shell prompt. I executed all Linux commands with root privileges (sudo su), but you can prefix each command with sudo if you like. Many of the command parameters and settings in the configuration files are case sensitive, so it is very important to use exactly the same case for each step as is used in the example below!

Our example is for the following fictitious configuration:

## Computer Type Command/action Comments
1 DC Command setspn -s HTTP/webserver1.company.com srvaccount1 Register SPN for the web site in the properties of the account srvaccount1
2 DC Command ktpass /out temp.keytab /princ srvaccount1@COMPANY.COM -SetUPN /mapuser srvaccount1 /crypto AES256-SHA1 /ptype KRB5_NT_PRINCIPAL /pass THEpassword -SetPass +DumpSalt /target dc1.company.com Generate and output secret key and key serial number (vno) for AES algorithm
3 DC Action Copy the key and vno values for AES algorithm from the output of the previous commands to a temporary text file We only need the values written to screen by the previous ktpass command, the generated file temp.keytab won’t be used
4 DC Command ktpass /out temp.keytab /princ srvaccount1@COMPANY.COM -SetUPN /mapuser srvaccount1 /crypto RC4-HMAC-NT /ptype KRB5_NT_PRINCIPAL /pass THEpassword -SetPass +DumpSalt /target dc1.company.com Generate and output secret key and key serial number (vno) for RC4 algorithm
5 DC Action Copy the key and vno values for RC4 algorithm from the output of the previous commands to a temporary text file We only need the values written to screen by the previous ktpass command, the generated file temp.keytab won’t be used
6 DC Action Create A type DNS record webserver1.company.com, pointing directly to the IP address of the Linux web server There are additional issues to be aware of if you use CNAME DNS aliases, as is explained later in this document 1
7 Linux server Action Install apache2 Install apache2 if it’s not already running on your Linux box
8 Linux server Command apt install libapache2-mod-auth-kerb Install mod_auth_kerb Kerberos authentication module for Apache
9 Linux server Command apt install krb5-user Install krb5-user package - kerberos 5 client library
10 Linux server Command nano /etc/krb5.conf Open Kerberos 5 system-wide configuration file /etc/krb5.conf for editing
11 Linux server Action Replace the text in /etc/krb5.conf file with the contents of the krb5.conf block below Configure system-wide Kerberos settings
12 Linux server Action Ctrl + O, Ctrl + X Save file /etc/krb5.conf and exit nano
13 Linux server Command nano /etc/apache2/sites-enabled/000-default.conf Edit the file /etc/apache2/sites-enabled/000-default.conf - definition of the default apache2 web site
14 Linux server Action Add <Location> block inside the <VirtualHost> section - use the contents of the block Location Configure mod_auth_kerb settings 4
15 Linux server Action Ctrl + O, Ctrl + X Save file /etc/apache2/sites-enabled/000-default.conf and exit nano
16 Linux server Command ktutil Start ktutil tool (part of the krb5-user package) which is used to manipulate keytab files
17 Linux server Command list Run list subcommand to verify that you have no entries in the currently open empty new keytab file
18 Linux server Command addent -key -p HTTP/webserver1.company.com@COMPANY.COM -k n -e aes256-cts Run addent subcommand to add AES key for the HTTP SPN associated with the web server FQDN 1. The n parameter must be substituted with the vno value that you captured from the output of the ktpass command in step 3. The command will ask you to enter the key in hexadecimal format.
19 Linux server Action Enter the AES256 key value from the output of the ktpass command in step 3 Enter 32 hexadecimal digits - the generated Kerberos secret key for AES256 encryption method derived from the current password and account name of the service account srvaccount1. EXCLUDE THE ‘0x’ PREFIX WHEN YOU ENTER THE DIGITS!
20 Linux server Command addent -key -p HTTP/webserver1.company.com@COMPANY.COM -k n -e RC4-HMAC Run addent subcommand to add RC4 key for the HTTP SPN associated with the web server FQDN 1. The n parameter must be substituted with the vno value that you captured from the output of the ktpass command in step 5. The command will ask you to enter the key in hexadecimal format.
21 Linux server Action Enter the RC4 key value from the output of the ktpass command in step 5 Enter 16 hexadecimal digits - the generated Kerberos secret key for RC4 encryption method derived from the current password and account name of the service account srvaccount1. EXCLUDE THE ‘0x’ PREFIX WHEN YOU ENTER THE DIGITS!
22 Linux server Command list Run list subcommand to verify that now you have two entries for HTTP/webserver1.company.com@COMPANY.COM in the currently open new keytab file - one for AES256 key and the other one for RC4
23 Linux server Command wkt /etc/apache2/kerb.keytab Save the open keytab file with the two entries as /etc/apache2/kerb.keytab
24 Linux server Command q Quit the ktpass interactive prompt and return to the shell
25 Linux server Command chown root:www-data /etc/apache2/kerb.keytab Change the owner and group for the newly generated kerb.keytab file to grant access to this file for the apache process
26 Linux server Command chmod 0640 /etc/apache2/kerb.keytab Set the file system permissions for the newly generated kerb.keytab
27 Linux server Command systemctl restart apache2 Restart apache to apply the configuration changes
28 Client computer Action Internet Explorer settings -> Security -> select Local intranet, click Sites -> Advanced, , add the web site URL http://webserver1.company.com Internet Explorer (and Chrome) will only try to send the cached Windows Kerberos credentials automatically to the sites in the Local intranet zone

krb5.conf

[libdefaults]
    default_realm = COMPANY.COM
    default_tkt_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac
    default_tgs_enctypes = aes256-cts-hmac-sha1-96  rc4-hmac
    permitted_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac


[realms]
    COMPANY.COM = {
            kdc = dc1.company.com
            kdc = dc2.company.com
            admin_server = dc1.company.com
    }

[domain_realm]
    .company.com = COMPANY.COM
    company.com = COMPANY.COM

<Location>

<Location />
  AuthType Kerberos
  AuthName "Active Directory"
  KrbAuthRealms COMPANY.COM
  KrbServiceName HTTP
  Krb5Keytab /etc/apache2/kerb.keytab
  KrbMethodNegotiate On
  KrbMethodK5Passwd Off
  require valid-user
</Location>

Testing the results

If you correctly configured all components, you should be able to launch Internet Explorer, Edge or Chrome browser on a domain joined Windows machine and open http://webserver1.company.com without any password prompt. You can also verify if a Kerberos ticket was issued by the KDC (domain controller) to your client system to be used for authentication against the web server. Type the following command in the CMD prompt:

klist

You should get the list of Kerberos tickets for various services that your system is talking to 1. Find the ticket for http://webserver1.company.com and check the KerbTicket Encryption Type and Session Key Type fields. These two fields specify the encryption method that the KDC used for encrypting the issued service ticket and the requested encryption method that will be used for the session key between the client and the server, respectively 5.

Background information

How Kerberos authentication works

First of all, you have to define how your web site will be accessed by the clients from the DNS and IP address assignment point of view. There can be many possible configurations, and we have to know exactly how DNS records are configured and how IP connections from the clients to the web server are routed. The main thing to remember is that Kerberos clients (web browsers on Windows clients) use DNS lookups and special Kerberos protocol functionality to find out which AD account is the identity of the web server they are connecting to. In other words, they need to know the service account name for the web server in order to generate a valid Kerberos service ticket which can only be used by this particular account. The whole process looks like that:

SPN Algorithm Secret key
HTTP/webserver.company.com AES256 f1a015ea515c317737aa78f3e19eec41b7e3b0f723bfde2d973069e8296f3e9f9
HTTP/webserver.company.com RC4 9472a6e31280efe2acdac7d51398fa89

Different scenarios for DNS configuration and hosting multiple sites on one web server

In the table below, I outlined two possible scenarios and my recommendations for DNS and keytab configuration.

## Scenario DNS configuration Service account/keytab configuration Comments
1 One web site with public URL the same as the web server FQDN host FQDN A record pointing to the server’s IP address One service account, keytab contains two entries for the server’s FQDN with two keys for AES and RC4 This simplest scenario is used in the example section
2 Two or more web sites, their public URLs are different from the server’s FQDN, same service account Server A record: srv1.company.com; site1 CNAME: site1.company.com -> srv1.company.com; site2 CNAME: site2.company.com -> srv1.company.com; One service account for both sites, keytab contains two entries for the server’s FQDN HTTP/srv1.company.com@COMPANY.COM with two keys for AES and RC4 for the same service account Web browser use CNAME canonization for both sites and request Kerberos service ticket for the server’s FQDN srv1.company.com from the KDC

References

  1. Mod_auth_kerb official page
  2. The RC4-HMAC Kerberos Encryption Types Used by Microsoft Windows
  3. How-to – Single sign on with Active directory and Apache
  4. How the Kerberos Version 5 Authentication Protocol Works
  5. Kerberos Keytabs – Explained
  6. All you need to know about Keytab files
  7. Encryption Type Selection in Kerberos Exchanges
  8. ktutil - problems generating AES keys (salt?)
  9. Apache sends wrong server principal name to Kerberos
  10. Kerberos configuration known issues
  11. The Chromium Projects - HTTP authentication
  12. Why you can still have duplicate SPNs in AD 2012 R2 and AD 2016

Notes

  1. I have long been under wrong impression that browsers (IE and Chrome) can initiate Kerberos authentication with the web server only if the web server URL is added to the “Local intranet” zone where the “Automatic logon” option is enabled by default. And I also wrongly presumed that Kerberos authentication will not work from Windows machines not joined to the AD domain. But as I closely looked into this issue I realized that browsers would still be able to authenticate via Kerberos protocol if the target web site URL is not in the “Local intranet” zone, or even if the client machine is not a member of the domain at all, as long as the client has network connectivity with the KDC for all required ports. The difference is that with “Automatic logon” enabled authentication if completely transparent (100% Single Sign On) and the user is not asked for his password whereas in the opposite scenario the login/password prompt pops up in the browser. Besides, you can only see the cached Kerberos tickets via klist command in the “Automatic logon” scenario (web site in the “Local intranet” zone). Otherwise, if the user is prompted for his password by the browser, you can see in Wireshark that the Kerberos ticket is sent to the web server on the wire but klist command output won’t show it.  2 3 4 5

  2. It seems that the Kerberos auth module and the krb5user library are only looking for those entries in the keytab file where the hostname matches the value configured in the “/etc/hosts” file. There many possible scenarios for DNS configuration and the only one of them which is straightforward to configure is when the public FQDN for your web site matches the FQDN of your server associated with the server’s own IP address in the /etc/hosts file. The example configuration in this document describes just that scenario. However, there are other ways to configure DNS and Kerberos keytab file for your web server. Please refer to the Different scenarios for DNS configuration and hosting multiple sites on one web server section of this document for more information on this subject. Please note, that there should be a way to force mod_auth_kerb and the client library krb5-user to accept any entries in the keytab file and not only those matching the FQDN hostname configured in the /etc/hosts file. To do this, you can add KrbServiceName Any option to the / section of the apache config file, according to this resource. However, I had no luck with this option, no matter how I tried. But still, perhaps it could’ve been just the wrong version of binaries that I used and this option would still work with your setup.  2

  3. There is also an option to change the password to a random value and generate keytab secret keys for this newly changed password value. In this case DO NOT use ‘-SetPass’ option and add the ‘+rndPass’ option insted. See this resource for more information. 

  4. The mod_auth_kerb option KrbMethodK5Passwd On will enable the fallback to HTTP Basic authentication. However, as the password is not encrypted when this authentication scheme is used, this option must not be enabled if your site is accessible via plain HTTP protocol with no SSL/TLS encryption. This option, if used with mandatory SSL/TLS encryption of HTTPS traffic between the browser and the server, is the only way to authenticate clients and browser which do not support Kerberos authentication. In that respect, HTTP Basic authentication plays a role similar to that of NTLM in Microsoft Windows/IIS environment, which also serves as the fallback authentication mechanism when Kerberos cannot be used. The examples of clients, which do not support Kerberos and will require KrbMethodK5Passwd On option are mobile clients (smartphones, tablets and etc.), corporate client machines connecting to the web server over the Internet via the public IP (out of office scenario), in which case the domain controllers and the KDC service are behind the firewall and cannot be contacted 1

  5. This document describes how different encryption types are selected for different Kerberos messages and exchanges. The rules for encryption types are very complex and vary from one Windows version to another. However, there is a small hack, which can force your Windows client (tested on Windows 10) to use only the strongest available algorithm AES256 for all Kerberos exchanges. Launch regedit and add a new DWORD value DefaultEncryptionType under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters, set it to 18 (decimal) or 0x12 (hexadecimal), which will enforce AES256 encryption for Kerberos pre-authentication and make KDC use AES256 when it will be issuing service tickets. You’ll need to reboot to apply this settings.  2