Kerberos

Kerberos is a network authentication system based on the principal of a trusted third party. The other two parties being the user and the service the user wishes to authenticate to. Not all services and applications can use Kerberos, but for those that can, it brings the network environment one step closer to being Single Sign On (SSO).

This section covers installation and configuration of a Kerberos server, and some example client configurations.

Overview

If you are new to Kerberos there are a few terms that are good to understand before setting up a Kerberos server. Most of the terms will relate to things you may be familiar with in other environments:

  • Principal: any users, computers, and services provided by servers need to be defined as Kerberos Principals.

  • Instances: are used for service principals and special administrative principals.

  • Realms: the unique realm of control provided by the Kerberos installation. Think of it as the domain or group your hosts and users belong to. Convention dictates the realm should be in uppercase. By default, ubuntu will use the DNS domain converted to uppercase (EXAMPLE.COM) as the realm.

  • Key Distribution Center: (KDC) consist of three parts, a database of all principals, the authentication server, and the ticket granting server. For each realm there must be at least one KDC.

  • Ticket Granting Ticket: issued by the Authentication Server (AS), the Ticket Granting Ticket (TGT) is encrypted in the user’s password which is known only to the user and the KDC.

  • Ticket Granting Server: (TGS) issues service tickets to clients upon request.

  • Tickets: confirm the identity of the two principals. One principal being a user and the other a service requested by the user. Tickets establish an encryption key used for secure communication during the authenticated session.

  • Keytab Files: are files extracted from the KDC principal database and contain the encryption key for a service or host.

To put the pieces together, a Realm has at least one KDC, preferably more for redundancy, which contains a database of Principals. When a user principal logs into a workstation that is configured for Kerberos authentication, the KDC issues a Ticket Granting Ticket (TGT). If the user supplied credentials match, the user is authenticated and can then request tickets for Kerberized services from the Ticket Granting Server (TGS). The service tickets allow the user to authenticate to the service without entering another username and password.

Kerberos Server

Installation

For this discussion, we will create a MIT Kerberos domain with the following features (edit them to fit your needs):

Note

It is strongly recommended that your network-authenticated users have their uid in a different range (say, starting at 5000) than that of your local users.

Before installing the Kerberos server a properly configured DNS server is needed for your domain. Since the Kerberos Realm by convention matches the domain name, this section uses the EXAMPLE.COM domain configured in ??? of the DNS documentation.

Also, Kerberos is a time sensitive protocol. So if the local system time between a client machine and the server differs by more than five minutes (by default), the workstation will not be able to authenticate. To correct the problem all hosts should have their time synchronized using the same Network Time Protocol (NTP) server. For details on setting up NTP see ???.

The first step in creating a Kerberos Realm is to install the krb5-kdc and krb5-admin-server packages. From a terminal enter:

sudo apt install krb5-kdc krb5-admin-server

You will be asked at the end of the install to supply the hostname for the Kerberos and Admin servers, which may or may not be the same server, for the realm.

Note

By default the realm is created from the KDC’s domain name.

Next, create the new realm with the kdb5_newrealm utility:

sudo krb5_newrealm

Configuration

The questions asked during installation are used to configure the /etc/krb5.conf file. If you need to adjust the Key Distribution Center (KDC) settings simply edit the file and restart the krb5-kdc daemon. If you need to reconfigure Kerberos from scratch, perhaps to change the realm name, you can do so by typing

sudo dpkg-reconfigure krb5-kdc

Once the KDC is properly running, an admin user – the admin principal – is needed. It is recommended to use a different username from your everyday username. Using the kadmin.local utility in a terminal prompt enter:

sudo kadmin.local
Authenticating as principal root/admin@EXAMPLE.COM with password.
kadmin.local: addprinc steve/admin
WARNING: no policy specified for steve/admin@EXAMPLE.COM; defaulting to no policy
Enter password for principal "steve/admin@EXAMPLE.COM": 
Re-enter password for principal "steve/admin@EXAMPLE.COM": 
Principal "steve/admin@EXAMPLE.COM" created.
kadmin.local: quit

In the above example steve is the Principal, /admin is an Instance, and @EXAMPLE.COM signifies the realm. The “every day” Principal, a.k.a. the user principal, would be steve@EXAMPLE.COM, and should have only normal user rights.

Note

Replace EXAMPLE.COM and steve with your Realm and admin username.

Next, the new admin user needs to have the appropriate Access Control List (ACL) permissions. The permissions are configured in the /etc/krb5kdc/kadm5.acl file:

steve/admin@EXAMPLE.COM        *

This entry grants steve/admin the ability to perform any operation on all principals in the realm. You can configure principals with more restrictive privileges, which is convenient if you need an admin principal that junior staff can use in Kerberos clients. Please see the kadm5.acl man page for details.

Now restart the krb5-admin-server for the new ACL to take affect:

sudo systemctl restart krb5-admin-server.service

The new user principal can be tested using the kinit utility:

kinit steve/admin
steve/admin@EXAMPLE.COM's Password:

After entering the password, use the klist utility to view information about the Ticket Granting Ticket (TGT):

klist
Credentials cache: FILE:/tmp/krb5cc_1000
        Principal: steve/admin@EXAMPLE.COM

  Issued           Expires          Principal
Jul 13 17:53:34  Jul 14 03:53:34  krbtgt/EXAMPLE.COM@EXAMPLE.COM

Where the cache filename krb5cc_1000 is composed of the prefix krb5cc_ and the user id (uid), which in this case is 1000. You may need to add an entry into the /etc/hosts for the KDC so the client can find the KDC. For example:

192.168.0.1   kdc01.example.com       kdc01

Replacing 192.168.0.1 with the IP address of your KDC. This usually happens when you have a Kerberos realm encompassing different networks separated by routers.

The best way to allow clients to automatically determine the KDC for the Realm is using DNS SRV records. Add the following to /etc/named/db.example.com:

_kerberos._udp.EXAMPLE.COM.     IN SRV 1  0 88  kdc01.example.com.
_kerberos._tcp.EXAMPLE.COM.     IN SRV 1  0 88  kdc01.example.com.
_kerberos._udp.EXAMPLE.COM.     IN SRV 10 0 88  kdc02.example.com. 
_kerberos._tcp.EXAMPLE.COM.     IN SRV 10 0 88  kdc02.example.com. 
_kerberos-adm._tcp.EXAMPLE.COM. IN SRV 1  0 749 kdc01.example.com.
_kpasswd._udp.EXAMPLE.COM.      IN SRV 1  0 464 kdc01.example.com.

Note

Replace EXAMPLE.COM, kdc01, and kdc02 with your domain name, primary KDC, and secondary KDC.

See ??? for detailed instructions on setting up DNS.

Your new Kerberos Realm is now ready to authenticate clients.

Secondary KDC

Once you have one Key Distribution Center (KDC) on your network, it is good practice to have a Secondary KDC in case the primary becomes unavailable. Also, if you have Kerberos clients that are in different networks (possibly separated by routers using NAT), it is wise to place a secondary KDC in each of those networks.

First, install the packages, and when asked for the Kerberos and Admin server names enter the name of the Primary KDC:

sudo apt install krb5-kdc krb5-admin-server

Once you have the packages installed, create the Secondary KDC’s host principal. From a terminal prompt, enter:

kadmin -q "addprinc -randkey host/kdc02.example.com"

Note

After, issuing any kadmin commands you will be prompted for your username/admin@EXAMPLE.COM principal password.

Extract the keytab file:

kadmin -q "ktadd -norandkey -k keytab.kdc02 host/kdc02.example.com"

There should now be a keytab.kdc02 in the current directory, move the file to /etc/krb5.keytab:

sudo mv keytab.kdc02 /etc/krb5.keytab

Note

If the path to the keytab.kdc02 file is different adjust accordingly.

Also, you can list the principals in a Keytab file, which can be useful when troubleshooting, using the klist utility:

sudo klist -k /etc/krb5.keytab

The -k option indicates the file is a keytab file.

Next, there needs to be a kpropd.acl file on each KDC that lists all KDCs for the Realm. For example, on both primary and secondary KDC, create /etc/krb5kdc/kpropd.acl:

host/kdc01.example.com@EXAMPLE.COM
host/kdc02.example.com@EXAMPLE.COM

Create an empty database on the Secondary KDC:

sudo kdb5_util -s create

Now start the kpropd daemon, which listens for connections from the kprop utility. kprop is used to transfer dump files:

sudo kpropd -S

From a terminal on the Primary KDC, create a dump file of the principal database:

sudo kdb5_util dump /var/lib/krb5kdc/dump

Extract the Primary KDC’s keytab file and copy it to /etc/krb5.keytab:

kadmin -q "ktadd -k keytab.kdc01 host/kdc01.example.com"
sudo mv keytab.kdc01 /etc/krb5.keytab

Note

Make sure there is a host for kdc01.example.com before extracting the Keytab.

Using the kprop utility push the database to the Secondary KDC:

sudo kprop -r EXAMPLE.COM -f /var/lib/krb5kdc/dump kdc02.example.com

Note

There should be a SUCCEEDED message if the propagation worked. If there is an error message check /var/log/syslog on the secondary KDC for more information.

You may also want to create a cron job to periodically update the database on the Secondary KDC. For example, the following will push the database every hour (note the long line has been split to fit the format of this document):

# m h  dom mon dow   command
0 * * * * /usr/sbin/kdb5_util dump /var/lib/krb5kdc/dump && 
/usr/sbin/kprop -r EXAMPLE.COM -f /var/lib/krb5kdc/dump kdc02.example.com

Back on the Secondary KDC, create a stash file to hold the Kerberos master key:

sudo kdb5_util stash

Finally, start the krb5-kdc daemon on the Secondary KDC:

sudo systemctl start krb5-kdc.service

The Secondary KDC should now be able to issue tickets for the Realm. You can test this by stopping the krb5-kdc daemon on the Primary KDC, then by using kinit to request a ticket. If all goes well you should receive a ticket from the Secondary KDC. Otherwise, check /var/log/syslog and /var/log/auth.log in the Secondary KDC.

Kerberos Linux Client

This section covers configuring a Linux system as a Kerberos client. This will allow access to any kerberized services once a user has successfully logged into the system.

Installation

In order to authenticate to a Kerberos Realm, the krb5-user and libpam-krb5 packages are needed, along with a few others that are not strictly necessary but make life easier. To install the packages enter the following in a terminal prompt:

sudo apt install krb5-user libpam-krb5 libpam-ccreds auth-client-config

The auth-client-config package allows simple configuration of PAM for authentication from multiple sources, and the libpam-ccreds will cache authentication credentials allowing you to login in case the Key Distribution Center (KDC) is unavailable. This package is also useful for laptops that may authenticate using Kerberos while on the corporate network, but will need to be accessed off the network as well.

Configuration

To configure the client in a terminal enter:

sudo dpkg-reconfigure krb5-config

You will then be prompted to enter the name of the Kerberos Realm. Also, if you don’t have DNS configured with Kerberos SRV records, the menu will prompt you for the hostname of the Key Distribution Center (KDC) and Realm Administration server.

The dpkg-reconfigure adds entries to the /etc/krb5.conf file for your Realm. You should have entries similar to the following:

[libdefaults]
        default_realm = EXAMPLE.COM
...
[realms]
        EXAMPLE.COM = {
                kdc = 192.168.0.1
                admin_server = 192.168.0.1
        }

Note

If you set the uid of each of your network-authenticated users to start at 5000, as suggested in Installation, you can then tell pam to only try to authenticate using Kerberos users with uid > 5000:

# Kerberos should only be applied to ldap/kerberos users, not local ones.
for i in common-auth common-session common-account common-password; do
 sudo sed -i -r \ 
 -e 's/pam_krb5.so minimum_uid=1000/pam_krb5.so minimum_uid=5000/' \ 
 /etc/pam.d/$i 
done 

This will avoid being asked for the (non-existent) Kerberos password of a locally authenticated user when changing its password using passwd.

You can test the configuration by requesting a ticket using the kinit utility. For example:

kinit steve@EXAMPLE.COM
Password for steve@EXAMPLE.COM:

When a ticket has been granted, the details can be viewed using klist:

klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: steve@EXAMPLE.COM

Valid starting     Expires            Service principal
07/24/08 05:18:56  07/24/08 15:18:56  krbtgt/EXAMPLE.COM@EXAMPLE.COM
        renew until 07/25/08 05:18:57


Kerberos 4 ticket cache: /tmp/tkt1000
klist: You have no tickets cached

Next, use the auth-client-config to configure the libpam-krb5 module to request a ticket during login:

sudo auth-client-config -a -p kerberos_example

You will should now receive a ticket upon successful login authentication.

Resources

Kerberos and LDAP

Most people will not use Kerberos by itself; once an user is authenticated (Kerberos), we need to figure out what this user can do (authorization). And that would be the job of programs such as LDAP.

Replicating a Kerberos principal database between two servers can be complicated, and adds an additional user database to your network. Fortunately, MIT Kerberos can be configured to use an LDAP directory as a principal database. This section covers configuring a primary and secondary kerberos server to use OpenLDAP for the principal database.

Note

The examples presented here assume MIT Kerberos and OpenLDAP.

Configuring OpenLDAP

First, the necessary schema needs to be loaded on an OpenLDAP server that has network connectivity to the Primary and Secondary KDCs. The rest of this section assumes that you also have LDAP replication configured between at least two servers. For information on setting up OpenLDAP see OpenLDAP Server.

It is also required to configure OpenLDAP for TLS and SSL connections, so that traffic between the KDC and LDAP server is encrypted. See TLS for details.

Note

cn=admin,cn=config is a user we created with rights to edit the ldap database. Many times it is the RootDN. Change its value to reflect your setup.

  • To load the schema into LDAP, on the LDAP server install the krb5-kdc-ldap package. From a terminal enter:

    sudo apt install krb5-kdc-ldap
    
  • Next, extract the kerberos.schema.gz file:

    sudo gzip -d /usr/share/doc/krb5-kdc-ldap/kerberos.schema.gz
    sudo cp /usr/share/doc/krb5-kdc-ldap/kerberos.schema /etc/ldap/schema/
    
  • The kerberos schema needs to be added to the cn=config tree. The procedure to add a new schema to slapd is also detailed in Modifying the slapd Configuration Database.

    First, create a configuration file named schema_convert.conf, or a similar descriptive name, containing the following lines:

    include /etc/ldap/schema/core.schema
    include /etc/ldap/schema/collective.schema
    include /etc/ldap/schema/corba.schema
    include /etc/ldap/schema/cosine.schema
    include /etc/ldap/schema/duaconf.schema
    include /etc/ldap/schema/dyngroup.schema
    include /etc/ldap/schema/inetorgperson.schema
    include /etc/ldap/schema/java.schema
    include /etc/ldap/schema/misc.schema
    include /etc/ldap/schema/nis.schema
    include /etc/ldap/schema/openldap.schema
    include /etc/ldap/schema/ppolicy.schema
    include /etc/ldap/schema/kerberos.schema
    

    Create a temporary directory to hold the LDIF files:

    mkdir /tmp/ldif_output
    

    Now use slapcat to convert the schema files:

    slapcat -f schema_convert.conf -F /tmp/ldif_output -n0 -s \
    "cn={12}kerberos,cn=schema,cn=config" > /tmp/cn=kerberos.ldif
    

    Change the above file and path names to match your own if they are different.

    Edit the generated /tmp/cn\=kerberos.ldif file, changing the following attributes:

    dn: cn=kerberos,cn=schema,cn=config
    ...
    cn: kerberos
    

    And remove the following lines from the end of the file:

    structuralObjectClass: olcSchemaConfig
    entryUUID: 18ccd010-746b-102d-9fbe-3760cca765dc
    creatorsName: cn=config
    createTimestamp: 20090111203515Z
    entryCSN: 20090111203515.326445Z#000000#000#000000
    modifiersName: cn=config
    modifyTimestamp: 20090111203515Z
    

    The attribute values will vary, just be sure the attributes are removed.

    Load the new schema with ldapadd:

    sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /tmp/cn\=kerberos.ldif
    

    Add an index for the krb5principalname attribute:

    sudo ldapmodify -Q -Y EXTERNAL -H ldapi:///
    
    dn: olcDatabase={1}mdb,cn=config
    add: olcDbIndex
    olcDbIndex: krbPrincipalName eq,pres,sub
    
    modifying entry "olcDatabase={1}mdb,cn=config"
    

    Finally, update the Access Control Lists (ACL):

    sudo ldapmodify -Q -Y EXTERNAL -H ldapi:///
    
    dn: olcDatabase={1}mdb,cn=config
    replace: olcAccess
    olcAccess: to attrs=userPassword,shadowLastChange,krbPrincipalKey by
     dn="cn=admin,dc=example,dc=com" write by anonymous auth by self write by * none
    -
    add: olcAccess
    olcAccess: to dn.base="" by * read
    -
    add: olcAccess
    olcAccess: to * by dn="cn=admin,dc=example,dc=com" write by * read
    
    modifying entry "olcDatabase={1}mdb,cn=config"
    

That’s it, your LDAP directory is now ready to serve as a Kerberos principal database.

Primary KDC Configuration

With OpenLDAP configured it is time to configure the KDC.

  • First, install the necessary packages, from a terminal enter:

    sudo apt install krb5-kdc krb5-admin-server krb5-kdc-ldap
    
  • Now edit /etc/krb5.conf adding the following options to under the appropriate sections:

    [libdefaults]
            default_realm = EXAMPLE.COM
    
    ...
    
    [realms]
            EXAMPLE.COM = {
                    kdc = kdc01.example.com
                    kdc = kdc02.example.com
                    admin_server = kdc01.example.com
                    admin_server = kdc02.example.com
                    default_domain = example.com
                    database_module = openldap_ldapconf
            }
    
    ...
    
    [domain_realm]
            .example.com = EXAMPLE.COM
    
    
    ...
    
    [dbdefaults]
            ldap_kerberos_container_dn = cn=krbContainer,dc=example,dc=com
    
    [dbmodules]
            openldap_ldapconf = {
                    db_library = kldap
                    ldap_kdc_dn = "cn=admin,dc=example,dc=com"
    
                    # this object needs to have read rights on
                    # the realm container, principal container and realm sub-trees
                    ldap_kadmind_dn = "cn=admin,dc=example,dc=com"
    
                    # this object needs to have read and write rights on
                    # the realm container, principal container and realm sub-trees
                    ldap_service_password_file = /etc/krb5kdc/service.keyfile
                    ldap_servers = ldaps://ldap01.example.com ldaps://ldap02.example.com
                    ldap_conns_per_server = 5
            }
    

    Note

    Change example.com, dc=example,dc=com, cn=admin,dc=example,dc=com, and ldap01.example.com to the appropriate domain, LDAP object, and LDAP server for your network.

  • Next, use the kdb5_ldap_util utility to create the realm:

    sudo kdb5_ldap_util -D  cn=admin,dc=example,dc=com create -subtrees \
    dc=example,dc=com -r EXAMPLE.COM -s -H ldap://ldap01.example.com
    
  • Create a stash of the password used to bind to the LDAP server. This password is used by the ldap_kdc_dn and ldap_kadmin_dn options in /etc/krb5.conf:

    sudo kdb5_ldap_util -D  cn=admin,dc=example,dc=com stashsrvpw -f \
    /etc/krb5kdc/service.keyfile cn=admin,dc=example,dc=com
    
  • Copy the CA certificate from the LDAP server:

    scp ldap01:/etc/ssl/certs/cacert.pem .
    sudo cp cacert.pem /etc/ssl/certs
    

    And edit /etc/ldap/ldap.conf to use the certificate:

    TLS_CACERT /etc/ssl/certs/cacert.pem
    

    Note

    The certificate will also need to be copied to the Secondary KDC, to allow the connection to the LDAP servers using LDAPS.

  • Start the Kerberos KDC and admin server:

    sudo systemctl start krb5-kdc.service
    sudo systemctl start krb5-admin-server.service
    

You can now add Kerberos principals to the LDAP database, and they will be copied to any other LDAP servers configured for replication. To add a principal using the kadmin.local utility enter:

sudo kadmin.local
Authenticating as principal root/admin@EXAMPLE.COM with password.
kadmin.local:  addprinc -x dn="uid=steve,ou=people,dc=example,dc=com" steve
WARNING: no policy specified for steve@EXAMPLE.COM; defaulting to no policy
Enter password for principal "steve@EXAMPLE.COM": 
Re-enter password for principal "steve@EXAMPLE.COM": 
Principal "steve@EXAMPLE.COM" created.

There should now be krbPrincipalName, krbPrincipalKey, krbLastPwdChange, and krbExtraData attributes added to the uid=steve,ou=people,dc=example,dc=com user object. Use the kinit and klist utilities to test that the user is indeed issued a ticket.

Note

If the user object is already created the -x dn="…" option is needed to add the Kerberos attributes. Otherwise a new principal object will be created in the realm subtree.

Last updated 5 months ago. Help improve this document in the forum.