Kerberos

Presentation

This documentation will explain how to use Active Directory as Kerberos server, and provide transparent authentication for one or multiple AD domains.

You can use Kerberos in LL::NG with the following authentication modules:

  • Kerberos (recommended): use Perl GSSAPI module, compatible with Apache and Nginx

  • Apache: use mod_auth_kerb or mod_auth_gssapi in Apache

Prerequisites

Example values

We will use the following values in our examples

  • EXAMPLE.COM: First AD domain

  • ACME.COM: Second AD domain

  • auth.example.com: DNS of the LL::NG portal

  • KERB_AUTH: AD account to generate the keytab for LL::NG server

Server time

It is mandatory that LL::NG servers and AD servers have the same time. It is recommended to use NTP to do this.

DNS

In our experience, we have observed the following limitations when using Kerberos for web applications in an Active Directory environment

  • auth.example.com must be registered in the DNS server as a A record. CNAME usually do not work

  • The reverse DNS (PTR) for auth.example.com’s IP address MUST point back to auth.example.com

Tip

If you have a SSO cluster, you must setup a Virtual IP in cluster and register this IP in DNS.

Tip

If you cannot configure the PTR record to point to the portal’s hostname, it may help to run the following command. Assuming that proxy.example.com is the PTR record of the portal’s IP address

setspn -s HTTP/proxy.example.com keytab-account

SSL

SSL is not mandatory, but it is strongly recommended. Your portal URL should be https://auth.example.com.

Web server configuration

Apache

Some Kerberos tickets, especially generated by Active Directory, can get too big for Apache’s default header size limit

Increase it in the global httpd.conf configuration

LimitRequestFieldSize 16384

Nginx

Some Kerberos tickets, especially generated by Active Directory, can get too big for Apache’s default header size limit

Increase it in your portal-nginx.conf configuration

large_client_header_buffers 4 16k;

Web browser configuration

Firefox

Type about:config in a tab and search for trusted. Then edit the property network.negotiate-auth.trusted-uris and set value example.com.

Internet Explorer / Edge / Chrome

Add https://auth.example.com as trusted site.

Check into security parameters that Kerberos authentication is allowed.

Single AD domain

Client Kerberos configuration

On LL::NG server, edit /etc/krb5.conf:

[libdefaults]
 default_realm = EXAMPLE.COM
 dns_lookup_kdc = false
 dns_lookup_realm = no
 ticket_lifetime = 24h
 forwardable = yes
 renewable = true

[realms]
 EXAMPLE.COM = {
  kdc = ad.example.com
  admin_server = ad.example.com
 }

[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM

You can check that Kerberos is working by trying to get a ticket for a user of the domain (for example coudot):

kinit coudot@EXAMPLE.COM

You should be prompted to enter password. Then list the tickets:

klist -e

You should see a krbtgt ticket:

Valid starting     Expires            Service principal
06/04/15 15:43:24  06/05/15 01:43:29  krbtgt/EXAMPLE.COM@EXAMPLE.COM
        renew until 06/05/15 15:43:24, Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96

You can then close the Kerberos session:

kdestroy

Obtain keytab file

You have to run this command on Active Directory:

ktpass -princ HTTP/auth.example.com@EXAMPLE.COM -mapuser KERB_AUTH@EXAMPLE.COM -crypto All -ptype KRB5_NT_PRINCIPAL -mapOp set -pass <PASSWORD> -out c:\auth.keytab

Attention

You must use the UPPERCASE value of the domain name when generating the keytab

Attention

The values passed in -crypto and -ptype depend on the Active Directory version and the windows version of the workstations. You can for example use RC4-HMAC-NT as crypto protocol if DES is not supported by workstations (this the case by default for Window 8 for example).

The file auth.keytab should then be copied (with a secure media) to the Linux server (for example in /etc/lemonldap-ng).

Change rights on keytab file:

chown apache /etc/lemonldap-ng/auth.keytab
chmod 600 /etc/lemonldap-ng/auth.keytab
# If you use SELinux
restorecon /etc/lemonldap-ng/auth.keytab

You can check the validity of the keytab file by trying to request a service ticket, and compare the result with the keytab content.

Open a Kerberos session (like done in the previous step):

kinit coudot@example.com

Request a service ticket:

kvno HTTP/auth.example.com@EXAMPLE.COM

The result of the command should be:

HTTP/auth.example.com@EXAMPLE.COM: kvno = 3

Read the service ticket:

klist -e

You should see this kind of ticket:

06/04/15 16:28:49  06/05/15 02:28:11  HTTP/auth.example.com@EXAMPLE.COM
        renew until 06/05/15 16:28:07, Etype (skey, tkt): arcfour-hmac, arcfour-hmac

You can close the Kerberos session:

kdestroy

Now you can compare the above result with the same request done through the keytab file:

klist -e -k -t /etc/lemonldap-ng/auth.keytab

The result of the command should be:

Keytab name: FILE:/etc/lemonldap-ng/auth.keytab
KVNO Timestamp         Principal
---- ----------------- --------------------------------------------------------
   3 01/01/70 01:00:00 HTTP/auth.example.com@EXAMPLE.COM (arcfour-hmac)

The important things to check are:

  • KVNO must be the same

  • Principal names must be the same

  • Encryption types must be the same

Multiple AD domains

Client Kerberos configuration

The two domains must be defined in /etc/krb5.conf:

[libdefaults]
 default_realm = EXAMPLE.COM
 dns_lookup_kdc = false
 dns_lookup_realm = no
 ticket_lifetime = 24h
 forwardable = yes
 renewable = true

[realms]
 EXAMPLE.COM = {
  kdc = ad.example.com
  admin_server = ad.example.com
  default_domain = EXAMPLE.COM
 }
 ACME.COM = {
  kdc = ad.acme.com
  admin_server = ad.acme.com
  }

[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM
 .acme.com = ACME.COM
 acme.com = ACME.COM

You should then be able to open a Kerberos session on each domain:

kinit coudot@EXAMPLE.COM
klist -e
kdestroy
kinit coudot@ACME.COM
klist -e
kdestroy

Obtain keytab file

You need to obtain a keytab for each node on each domain. This means the ktpass commands should be run on both AD.

Then you will have 2 keytab files for each node, for example:

  • node1-example.keytab

  • node1-acme.keytab

You need to concatenate the keytab files, thanks to ktutil command:

ktutil
ktutil: read_kt node1-example.keytab
ktutil: read_kt node1-acme.keytab
ktutil: write_kt /etc/lemonldap-ng/auth.keytab
ktutil: quit

You can then remove the original keytab files and protect the final keytab file:

chown apache /etc/lemonldap-ng/auth.keytab
chmod 600 /etc/lemonldap-ng/auth.keytab

Other resources

You can check these documentations to get more information: