Kerberos and 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.

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 the section called “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 the section called “TLS and SSL” for details.

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

    sudo apt-get 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 the section called “Further Configuration”.

    1. 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
      
    2. Create a temporary directory to hold the LDIF files:

      mkdir /tmp/ldif_output
      
    3. 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.

    4. 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
      
      [Note]

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

    5. Load the new schema with ldapadd:

      ldapadd -x -D cn=admin,cn=config -W -f /tmp/cn\=kerberos.ldif
      
    6. Add an index for the krb5principalname attribute:

      ldapmodify -x -D cn=admin,cn=config -W
      Enter LDAP Password:
      dn: olcDatabase={1}hdb,cn=config
      add: olcDbIndex
      olcDbIndex: krbPrincipalName eq,pres,sub
      
      modifying entry "olcDatabase={1}hdb,cn=config"
      
    7. Finally, update the Access Control Lists (ACL):

      ldapmodify -x -D cn=admin,cn=config -W
      Enter LDAP Password: 
      dn: olcDatabase={1}hdb,cn=config
      replace: olcAccess
      olcAccess: to attrs=userPassword,shadowLastChange,krbPrincipalKey by dn="cn=admin,dc=exampl
       e,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}hdb,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-get 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 = 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.

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.

Secondary KDC Configuration

Configuring a Secondary KDC using the LDAP backend is similar to configuring one using the normal Kerberos database.

  • First, install the necessary packages. In a terminal enter:

    sudo apt-get install krb5-kdc krb5-admin-server krb5-kdc-ldap
    
  • Next, edit /etc/krb5.conf to use the LDAP backend:

    [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 = 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
            }
    
  • Create the stash for the LDAP bind password:

    sudo kdb5_ldap_util -D  cn=admin,dc=example,dc=com stashsrvpw -f /etc/krb5kdc/service.keyfile cn=admin,dc=example,dc=com
    
  • Now, on the Primary KDC copy the /etc/krb5kdc/.k5.EXAMPLE.COM Master Key stash to the Secondary KDC. Be sure to copy the file over an encrypted connection such as scp, or on physical media.

    sudo scp /etc/krb5kdc/.k5.EXAMPLE.COM steve@kdc02.example.com:~
    sudo mv .k5.EXAMPLE.COM /etc/krb5kdc/
    
    [Note]

    Again, replace EXAMPLE.COM with your actual realm.

  • Finally, start the krb5-kdc daemon:

    sudo /etc/init.d/krb5-kdc start
    

You now have redundant KDCs on your network, and with redundant LDAP servers you should be able to continue to authenticate users if one LDAP server, one Kerberos server, or one LDAP and one Kerberos server become unavailable.

Resources