Kerberos

Software version5
Operating SystemRed Hat 6 and Debian 6
Last Update29/10/2012

Introduction

The purpose of this article is to explain how to implement strong SSO (Single Sign-On) authentication for a web application hosted on a local network Linux server with Apache via Kerberos on Windows 2003/2008 Server. Clients will be Windows or Linux machines participating in the AD (Active Directory) domain using a web browser.1

We can summarize the operation as follows: a user opens a session on the domain and navigates to a protected http page on the Intranet network. Usually, a box is displayed inviting the user to enter their username and password, even though they are already known to AD, since they entered the same information to connect to their Windows account. The purpose of Single Sign-On is to authenticate the user without them having to re-enter the same information multiple times.

Kerberos works with a system of tokens, which we will call ’tickets’. Authentication takes place in several steps:

Kerberos diagram

  1. The client workstation requests a ticket from the Kerberos server (here the Win2003 DC)
  2. The KDC returns a ticket, since the client is already identified on the network
  3. The client workstation formulates the request to the Web server including the ticket

Several advantages of this method:

  • The user identifies themselves only once and can then transparently access different services
  • The username and password are never transmitted over the network

Prerequisites

For the rest of the article, I will assume that you have the following elements:

  • A 2003 Server configured as a domain controller with DNS service enabled, and at least one user account (dc-1.local.domain)
  • A Linux server with Apache configured, capable of serving pages (lx-1.local.domain)
  • An XP or 2003 client registered on the domain, capable of opening a session with a domain account (pc-1.local.domain)

In addition to being sensitive to naming, Kerberos is sensitive to any time lag between different machines. To overcome this problem, I advise you to use an NTP service.

Finally, you need to choose a Kerberos realm, for example LOCAL.DOMAIN. Note that the realm is written in all uppercase. It is not necessarily the domain name, and there can be several realms on a network with a single domain. However, the realm is written in uppercase, for example LOCAL.DOMAIN.

Installation

Windows Server

Install the support tools2.

Linux Server

We will install the following packages:

  aptitude install krb5-clients krb5-config krb5-user libkrb53 libapache2-mod-auth-kerb
  

Configuration

Windows Active Directory

For each service to Kerberize, the following operations are to be planned to generate a Service Principal:

  • Creation of a user account for each service. I advise you to choose a name that allows you to identify the service concerned, for example intranet-1 in the Active Directory.
  • Generation of a KeyTab. This file is used to authenticate the Kerberized server (here the Web server) to the KDC:
  ktpass -princ HTTP/lx-1.local.domain@LOCAL.DOMAIN -crypto DES-CBC-MD5 -ptype KRB5_NT_PRINCIPAL -mapuser intranet-1 -pass azerty -out C:\temp\keytab.txt
  

Copy the generated file to the Linux server in /etc/krb5.keytab.

Linux Server

Start by securing the keytab copied previously:

  chown www-data:root /etc/krb5.keytab
chmod 640 /etc/krb5.keytab
  

Configure DNS:

  # /etc/resolv.conf
search local.domain
nameserver 192.168.22.1
  

Verify that modauthkerb is activated:

  a2enmod auth_kerb
  

Create a .htaccess or edit apache2.conf to secure the site:

  # .htaccess
<Files "*">
        <Limit GET POST>
                AuthName "Kerberos Login"
                AuthType Kerberos
                Krb5Keytab /etc/krb5.keytab
                KrbAuthRealms LOCAL.DOMAIN
                KrbMethodNegotiate On
                KrbMethodK5Passwd Off
                KrbVerifyKDC off
                Require valid-user
        </Limit>
</Files>
  

Reload your Apache server

I remind you that the realm is written in uppercase. In this example, we activate the SSO mode via Negotiate and disable password authentication; if automatic authentication is impossible, a 401 Authorization Required error page will be displayed.

The last file to configure is /etc/krb5.conf:

  # /etc/krb5.conf
[libdefaults]
        ticket_lifetime = 24000
        default_realm = LOCAL.DOMAIN
        dns_lookup_realm = true
        dns_lookup_kdc = false
        default_keytab_name = FILE:/etc/krb5.keytab

[realms]
        LOCAL.DOMAIN = {
                kdc = dc-1.local.domain
                admin_server = dc-1.local.domain
}

[domain_realm]
        .local.domain = LOCAL.DOMAIN
        local.domain = LOCAL.DOMAIN

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

Validation

At this stage, you should normally have a functional configuration. However, we will perform some checks because there are many possible configuration errors.

  • Connection test:
  kinit <username>@LOCAL.DOMAIN
  

Enter the user’s password; there should be no error.

The klist command allows you to check the status of tickets:

  > klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: <username>@LOCAL.DOMAIN

Valid starting     Expires            Service principal
08/12/09 11:42:08 08/12/09 18:22:08 krbtgt/LOCAL.DOMAIN@LOCAL.DOMAIN


Kerberos 4 ticket cache: /tmp/tkt0
klist: You have no tickets cached
  
  • If all is well, then check your service authentication:
  > kvno HTTP/lx-1.local.domain@LOCAL.DOMAIN
HTTP/lx-1.local.domain@LOCAL.DOMAIN: kvno = 28
  

There should be no error, but here are some classic error messages and their meaning:

  kvno: No credentials cache found while getting client principal name
  

You don’t have a valid ticket: run the command:

  > kinit <username>
kvno: Server not found in Kerberos database while getting credentials for HTTP/lx-1.local.domain@LOCAL.DOMAIN
  

Several possibilities here:

  • You have poorly generated your keytab; try regenerating it
  • You have assigned the same SPN to multiple users (see pitfalls)

Finally, this keytab test should not return an error:

  kinit -k -t /etc/krb5.keytab HTTP/lx-1.local.domain@LOCAL.DOMAIN
  

Web Browser

Internet Explorer

  • In the advanced options, check that Windows Authentication is enabled: “Enable Integrated Windows Authentication”
  • Then add the secured site to the Local intranet zone: http://lx-1.local.domain

Accept the changes, and navigate to http://lx-1.local.domain: the site appears without password authentication.

Firefox

Launch Firefox and type about:config in the address bar, then filter with the word auth. Modify network.negotiate-auth.trusted-uris and network.negotiate-auth.delegation-uris with the domain value “local.domain”.

FAQ

Service Name on Multiple Accounts

If you have created multiple accounts for experimentation, it’s not impossible that the same service name or SPN is associated with multiple accounts, which is not possible. An account must be unique for each Kerberized service (intranet-1, intranet-2…) and the same service name (HTTP/lx-1.local.domain@LOCAL.DOMAIN) cannot be associated with multiple accounts. If you have used ktpass to associate the same SPN with multiple accounts, use setspn to fix it:

  C:\Program Files\Support Tools>setspn
Usage: setspn [switches data] computername
Where "computername" can be the name or domain\name

Switches:
-R = reset HOST ServicePrincipalName
    Usage: setspn -R computername
-A = add arbitrary SPN
    Usage: setspn -A SPN computername
-D = delete arbitrary SPN
    Usage: setspn -D SPN computername
-L = list registered SPNs
    Usage: setspn [-L] computername
Examples:
setspn -R daserver1
It will register SPN "HOST/daserver1" and "HOST/{DNS of daserver1}"
setspn -A http/daserver daserver1
It will register SPN "http/daserver" for computer "daserver1"
setspn -D http/daserver daserver1
It will delete SPN "http/daserver" for computer "daserver1"
  

To list the SPNs associated with a user, use the “-L” option, to remove, use the “-D” option, for example:

  setspn -D HTTP/lx-1.local.domain lx-1
  

Choosing the Username

The username is free, however, the name must not already be used as a computer name or as a domain controller.

References

Last updated 29 Oct 2012, 07:46 +0200. history