Basic Kerberos configuration of intranet.example.com

The method described here as five steps:

  1. Install the mod_auth_kerb authentication module.
  2. Create a service principal <Principal> for the web server.
  3. Create a keytab for the service principal.
  4. Specify the authentication method to be used.
  5. Specify a list of authorized users or user groups.

First of all, you should make sure the clocktime of KDC, workstation and web server is in sync (5 minutes are the highest difference you may allow for Kerberos to work properly).

You may use NTP for that task.

Installing the mod_auth_kerb authentication module

Within an intranet.example.com shell, install the package:

$ sudo apt-get install libapache2-mod-auth-kerb krb5-user
Copied!

In additional to libapache2-mod-auth-kerb, this will install the dependency package krb5-config and then show you a configuration wizard asking for:

  • Default Kerberos version 5 realm. Use EXAMPLE.COM (in capital letters).
  • The KDC. My Active Directory server is ws2008r2.example.com, replace by your own. In a larger organization, you probably have two domain controllers, for redundancy reason.
  • The administration server. This is typically the same as the LDAP/Active Directory server or in case of multiple domain controllers, this should be normally set to the master.

Settings you provide are then stored within configuration file /etc/krb5.conf which should look like this after the wizard configuration:

[libdefaults]
    default_realm    = EXAMPLE.COM

[realms]
    EXAMPLE.COM = {
        kdc          = ws2008r2.example.com
        #kdc          = other-kdc.example.com
        #master_kdc   = ws2008r2.example.com
        admin_server = ws2008r2.example.com
    }

[domain_realm]
    .example.com     = EXAMPLE.COM

[logging]
    kdc              = SYSLOG:NOTICE
    admin_server     = SYSLOG:NOTICE
    default          = SYSLOG:NOTICE
Copied!

You should now check that Kerberos works on intranet.example.com. Do a basic check using kinit:

  1. Ensure that intranet can reach KDC ws2008rs2 via the network (ping, ...).
  2. Have a username and password in Windows Domain EXAMPLE.COM. In this example einstein is used as username.
  3. Within the shell, type:

    $ kinit einstein@EXAMPLE.COM
    Copied!

    If everything is OK the command will ask you for einstein's domain password and terminates without an error message.

  4. Finally use klist to show the initial ticket you have got from the KDC:

    $ klist
    Default principal: einstein@EXAMPLE.COM
    
    Valid starting    Expires           Service principal
    31/10/2014 13:12  31/10/2014 23:11  krbtgt/EXAMPLE.COM@EXAMPLE.COM
            renew until 01/11/2014 13:12
    Copied!

Creating a service principal for the web server

SPNEGO requires that a Kerberos service principal be created for the web server. The service name is defined to be HTTP, so for the server intranet.example.com the required service principal name is HTTP/intranet.example.com@EXAMPLE.COM.

  1. Create a dummy account in Windows Domain EXAMPLE.COM. It is used like a machine account but is nevertheless a standard user account. In this example the name of dummy account is kerbdummy1.
  2. Log in to the domain controller ws2008r2 and use the Windows command line tool ktpass to map the dummy account kerbdummy1 to the service principal HTTP/intranet.example.com@EXAMPLE.COM. You need that service principal to kerberize host intranet:

    C:\>ktpass
      -princ HTTP/intranet.example.com@EXAMPLE.COM
      -mapuser kerbdummy1@EXAMPLE.COM
      -crypto AES256-SHA1
      -ptype KRB5_NT_PRINCIPAL
      -pass very!$longp@ssw0rd
      -out C:\temp\intranetkeytab
    Copied!
  3. Copy file C:\\temp\\intranetkeytab from the domain controller ws2008r2 to the location where it should reside on host intranet, in our example /etc/apache2/http_intranet.keytab and make www-data its owner.

  4. Check if the KDC sends correct tickets by checking in detail:

    • ticket's kvno must match kvno in keytab
    • principal name in ticket must match the principal name in keytab
    $ kvno HTTP/intranet.example.com@EXAMPLE.COM
    HTTP/intranet.example.com@EXAMPLE.COM: kvno = 4
    
    $ klist -e
    Ticket cache: FILE:/tmp/krb5cc_0
    Default principal: HTTP/intranet.example.com@EXAMPLE.COM
    
    Valid starting    Expires           Service principal
    31/10/2014 14:53  01/11/2014 00:52  krbtgt/EXAMPLE.COM@EXAMPLE.COM
            renew until 01/11/2014 14:53, Etype (skey, tkt): aes256-cts-hmac-sha1-96, ...
    31/10/2014 15:09  01/11/2014 00:52  HTTP/intranet.example.com@EXAMPLE.COM
            renew until 01/11/2014 14:53, Etype (skey, tkt): arcfour-hmac, arcfour-hmac
    
    $ klist -e -k -t /etc/apache2/http_intranet.keytab
    Keytab name: FILE:http_intranet.keytab
    KVNO Timestamp        Principal
    ---- ---------------- ---------------------------------------------------------
       4 01/01/1970 01:00 HTTP/intranet.example.com@EXAMPLE.COM (aes256-cts-hmac-sha1-96)
    Copied!
  5. Check that the key has been correctly added to the keytab by attempting to use it to authenticate as the service principal, then view the resulting ticket-granting ticket using klist:

    $ kinit -k -t /etc/apache2/http_intranet.keytab HTTP/intranet.example.com
    $ klist
    Ticket cache: FILE:/tmp/krb5cc_0
    Default principal: HTTP/intranet.example.com@EXAMPLE.COM
    
    Valid starting    Expires           Service principal
    31/10/2014 14:11  01/11/2014 00:10  krbtgt/EXAMPLE.COM@EXAMPLE.COM
            renew until 01/11/2014 14:11
    Copied!

Specifying the authentication method to be used

Apache must be told which parts of which web sites are to use authentication provided by mod_auth_kerb. This is done using the AuthType directive with a value of Kerberos.

In order to protect the whole TYPO3 website, add following snippet to your virtual host configuration:

<Location />
    AuthType Kerberos
    AuthName "Intranet of example.com"
    KrbMethodNegotiate on
    KrbMethodK5Passwd off
    # Allow shorter username (without realm):
    KrbAuthRealms EXAMPLE.COM
    KrbServiceName HTTP
    Krb5Keytab /etc/apache2/http_intranet.keytab

    # Disable the verification tickets against local keytab to
    # prevent KDC spoofing attacks
    # It should be used only for testing purposes
    KrbVerifyKDC off
</Location>
Copied!

If you are using ``libapache2-mod-auth-gssapi``, add the following snippet instead:

<Location />
		SSLRequireSSL
		AuthType GSSAPI
		AuthName "Intranet of example.com"
		GssapiBasicAuth On
		GssapiCredStore keytab:/etc/apache2/http_intranet.keytab
		GssapiLocalName On
		require valid-user
</Location>
Copied!

Specifying a list of authorized users or user groups

Having an authentication method does not by itself restrict access to the web site until you disallow access by anonymous users using Require directive:

<Location />
    # ...
    Require valid-user
</Location>
Copied!

Please refer to the Apache documentation if you want to restrict access to certain users or groups (if so, you will certainly need to use another authorization module such as mod_authnz_ldap).

Final step is to reload the Apache configuration:

$ sudo apache2ctl configtest
Syntax OK
$ sudo service apache2 force-reload
Copied!

You will need to access your website from a machine within your domain or by authenticating with the basic authentication dialog, if enabled. TYPO3 will then read the authenticated username from $_SERVER['REMOTE_USER'] and silently create the frontend user session, if it does not exist yet. You do not need any frontend login plugin for your website.