RJ Systems
Linux System Administration
Home Tech Linux Links Consulting







Valid XHTML 1.0!

Valid CSS!

IPv6 test

Integrated Kerberos-OpenLDAP-OpenAFS consumer

Introduction

This page describes how to set up an additional OpenAFS file server, an OpenLDAP consumer server and an MIT Kerberos V slave server, all on the same host, with Kerberos using OpenLDAP as a back-end for its database. It depends on a previously configured server, klas1.example.com. Often referred to as the magic trio, when combined they form an enormously scalable open source network operating system that offers unequaled file system availability, excellent security and encryption, and a directory service for centralized management of access to workstations, servers, printers and other resources that are part of the same network.

In this example, everything is installed on a single host running Debian 5.0 (lenny). If followed properly, the step-by-step process should first produce an OpenLDAP consumer server with a replica of the Directory Information Tree (DIT) from klas1, followed by a Kerberos slave server that retrieves its data from the same DIT, and finally an additional OpenAFS server that will join the existing AFS cell as a file server and database server. The system relies also heavily on timestamps, so reasonably accurate time synchronization among all participating hosts is essential.

But, before the interesting parts can begin, it will first be necessary to install the operating system on a new host called klas2.example.com. A DNS server must also be available on the network with a zone file to which forward and reverse mappings can be added for this host. After the initial installation of the operating system, make sure these packages are installed on the system as well:

~# apt-get install ssh ntp ntpdate nmap

Afterwards, edit /etc/ntp.conf so that the machine synchronizes to a common NTP server (preferably a local one) and edit /etc/default/ntpdate to use the same host also. Now the installation of the new Kerberos-LDAP-AFS consumer server can begin.


1. Kerberos client install

First, run the following command to test if the MIT Kerberos V server installed previously is available on the network:

~# nmap klas1.example.com

This should be among the results:

PORT    STATE SERVICE
749/tcp open  kerberos-adm

If there is a problem, fix it first. If not, continue by installing these three packages:

~# apt-get install krb5-{config,user} libpam-krb5

A total of four packages are installed as a result, including one dependency:

krb5-config             1.22                               Configuration files for Kerberos Version 5
krb5-user               1.6.dfsg.4~beta1-5lenny2           Basic programs to authenticate using MIT Kerberos
libkadm55               1.6.dfsg.4~beta1-5lenny2           MIT Kerberos administration runtime libraries
libpam-krb5             3.11-4                             PAM module for MIT Kerberos

During the installation, the krb5-config package will automatically have the default realm set to EXAMPLE.COM, but a few questions have to be answered for it as well:

Kerberos servers for your realm: klas1.example.com
Administrative server for your Kerberos realm: klas.example.com

These settings, along with the default realm, are saved in /etc/krb5.conf.


2. Service princ & keytab

Use kadmin to create a Kerberos principal for the LDAP service and a matching keytab file by issuing a few commands:

~# kadmin -p admin
Authenticating as principal admin with password.
Password for admin@EXAMPLE.COM: cerastes
kadmin:  addprinc -randkey ldap/klas2.example.com
WARNING: no policy specified for ldap/klas2.example.com@EXAMPLE.COM; 
defaulting to no policy
Principal "ldap/klas2.example.com@EXAMPLE.COM" created.
kadmin:  ktadd ldap/klas2.example.com
Entry for principal ldap/klas2.example.com with kvno 3, encryption type
AES-256 CTS mode with 96-bit SHA-1 HMAC added to keytab
WRFILE:/etc/krb5.keytab.
Entry for principal ldap/klas2.example.com with kvno 3, encryption type
ArcFour with HMAC/md5 added to keytab 
WRFILE:/etc/krb5.keytab.
Entry for principal ldap/klas2.example.com with kvno 3, encryption type
Triple DES cbc mode with HMAC/sha1 added to keytab
WRFILE:/etc/krb5.keytab.
Entry for principal ldap/klas2.example.com with kvno 3, encryption type
DES cbc mode with CRC-32 added to keytab 
WRFILE:/etc/krb5.keytab.
kadmin:  q
~# _

The -randkey switch is used because a machine cannot enter a password. To list the keys in /etc/krb5.keytab, use the klist -ke command. A host (or service) principal and a keytab file should be created for and saved on all of the various client machines that are part of a Kerberos realm.


3. OpenLDAP install

Before starting the install process, run the following command to test if the previously installed OpenLDAP provider server is actually available on the network:

~# nmap klas1.example.com

This should be among the results:

PORT    STATE SERVICE
389/tcp open  ldap

If there is a problem, fix it first. Otherwise, install these two packages:

~# apt-get install slapd ldap-utils

A total of ten packages are installed as a result, including eight dependencies:

ldap-utils                 2.4.11-1                    OpenLDAP utilities
libdb4.2                   4.2.52+dfsg-5               Berkeley v4.2 Database Libraries [runtime]
libltdl3                   1.5.26-4+lenny1             A system independent dlopen wrapper for GNU libtool
libperl5.10                5.10.0-19lenny2             Shared Perl library
libsasl2-modules           2.1.22.dfsg1-23+lenny1      Cyrus SASL - pluggable authentication modules
libslp1                    1.2.1-7.5                   OpenSLP libraries
odbcinst1debian1           2.2.11-16                   Support library and helper program for accessing odbc ini file
psmisc                     22.6-1                      Utilities that use the proc filesystem
slapd                      2.4.11-1                    OpenLDAP server (slapd)
unixodbc                   2.2.11-16                   ODBC tools libraries

During the install process, an administrator password will be requested for slapd. Use cercobombus:

Administrator password: cercobombus
Confirm password: cercobombus

This password is actually inconsequential and will not be needed again.

Run the following command to test if the OpenLDAP server is actually running:

~# nmap klas2.example.com

This should be among the results:

PORT    STATE SERVICE
389/tcp open  ldap

Perform a quick test by generating an LDIF dump of the contents of a the database:

~# slapcat
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: example.com
dc: example
structuralObjectClass: organization
entryUUID: 5ae33b9c-bbe1-102e-8267-89b082b6c2ae
creatorsName:
createTimestamp: 20100304135537Z
entryCSN: 20100304135537.056327Z#000000#000#000000
modifiersName:
modifyTimestamp: 20100304135537Z

dn: cn=admin,dc=example,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e2NyeXB0fXVlYkJOWi52RnFmNVk=
structuralObjectClass: organizationalRole
entryUUID: 5ae421f6-bbe1-102e-8268-89b082b6c2ae
creatorsName:
createTimestamp: 20100304135537Z
entryCSN: 20100304135537.062573Z#000000#000#000000
modifiersName:
modifyTimestamp: 20100304135537Z

~# _

4. ldap.conf

Edit /etc/ldap/ldap.conf and use these two lines:

BASE    dc=example,dc=com
URI     ldap://klas2.example.com/

This configuration file is used to set system-wide defaults for LDAP clients.


5. Kerberos slave install

To set up a Kerberos slave server, install these two packages:

~# apt-get install krb5-{kdc,kdc-ldap}

These are also the only two packages that are installed as a result:

krb5-kdc                    1.6.dfsg.4~beta1-5lenny2             MIT Kerberos key server (KDC)
krb5-kdc-ldap               1.6.dfsg.4~beta1-5lenny2             MIT Kerberos key server (KDC) LDAP plugin

Since the idea is for Kerberos to use OpenLDAP as its back-end database, see to it that the Kerberos KDC and administrative services start up after slapd by changing the names of the symbolic links for their respective startup scripts:

~# mv /etc/rc2.d/S18krb5-kdc /etc/rc2.d/S20krb5-kdc
~# _

Following this automated configuration sequence for the package, a message appears reagrding krb5kdc: that the realm, EXAMPLE.COM cannot be initialize. This is because the realm, or rather the database for it, has not yet been created, but that is an issue that will be dealt with later.

Edit /etc/krb5kdc/kdc.conf and modify these two lines − the same as the Kerberos master server is configured:

        max_life = 1d 0h 0m 0s
        max_renewable_life = 90d 0h 0m 0s

6. krb524d bug

This version of Kerberos includes the V to IV ticket conversion daemon, krb524d. Unfortunately, it suffers from a type of bug, called a file descriptor leak, that manifests itself when running Kerberos together with an LDAP back-end. The bug causes slapd to slowly run out of file descriptors and eventually become unresponsive. Since it is unlikely that the Kerberos developers will address this problem (krb524d has been removed from current Kerberos V releases), a workaround is necessary. Create a file, called /usr/local/sbin/slapd-check, with the following contents:

#!/bin/sh

PATH=/usr/bin:/bin

openfiles=`lsof |grep -c slapd` 

daemonactive=`ps ax |grep -c krb524d`

if [ $daemonactive -gt 0 ] && [ $openfiles -gt 100 ]; then 

	killall krb524d
	krb524d -m
fi

exit 0

This script checks if krb524d is running, and if so, whether the number of files that slapd has open is greater than 100. If both these tests are true, krb524d is killed and restarted.

Make the new script executable:

~# chmod 750 /usr/local/sbin/slapd-check

Finally, have cron (crontab -e) run this script every fifteen minutes:

*/15 * * * * /usr/local/sbin/slapd-check

7. slapd.conf

Unzip and copy the Kerberos schema file to the OpenLDAP server's schema directory:

~# gunzip -c /usr/share/doc/krb5-kdc-ldap/kerberos.schema.gz > \
   /etc/ldap/schema/kerberos.schema

Edit /etc/ldap/slapd.conf and make a number of changes to it. Starting at the top of the file, add a line to include support for the Kerberos schema in the DIT:

# Schema and objectClass definitions
include         /etc/ldap/schema/core.schema
include         /etc/ldap/schema/cosine.schema
include         /etc/ldap/schema/nis.schema
include         /etc/ldap/schema/inetorgperson.schema
include         /etc/ldap/schema/kerberos.schema

Comment out the logging option, which will return it to its default value (256):

#loglevel "none"

Later on, after the configuration is finished and the whole system is working properly, it will likely be desirable to once again return the loglevel value to "none", because Kerberos tends to cause a lot of slapd log output (at least once every minute) as it accesses its back-end database. This level of logging may also affect performance.

Add an entry for a hard-coded root user, which is necessary for replication:

# rootdn          "cn=admin,dc=example,dc=com"

rootdn          "cn=manager"

It does not matter that the rootdn is not part of the DIT; just as long as it exists and is unique within the same system of replicating servers.

Add two new index directives for the uid and krb5principalname attributes:

index           objectClass eq
index           uid eq
index           krbPrincipalName eq,pres,sub

The first eq index will facilitate searches for uid entries, while the second will do the same for Kerberos principal entries. Both will speed up the login process.

Last, modify the ACLs to look like this:

access to attrs=userPassword,shadowLastChange
	by dn="cn=admin,dc=example,dc=com" read
        by anonymous auth
        by * none

access to dn.subtree="ou=krb5,dc=example,dc=com"
	by dn="cn=admin,dc=example,dc=com" read
	by dn="cn=adm-srv,ou=krb5,dc=example,dc=com" read
	by dn="cn=kdc-srv,ou=krb5,dc=example,dc=com" read
	by * none

access to dn.base=""
	by * read

access to *
        by users read
        by * none

It is pointless to add the same access directives here as on the provider to allow clients to write, since all OpenLDAP database synrepl replicas are strictly read-only. If clients attempt to write to it anyway, they will be given a referral (URL) to the provider before these ACLs are ever encountered.

Edit /etc/default/slapd and allow the LDAP service to listen for IPC connections (Unix domain sockets) by adding this line to the end of the file:

SLAPD_SERVICES="ldap:/// ldapi:///"

This will instruct slapd to listen on IPC, instead of only TCP port 389, which is the default.

Save all of these changes, but do not restart the LDAP service until later.


8. krb5.conf

Edit the Kerberos realm configuration file, /etc/krb5.conf. This file is initially created by the Debian installer and contains information about the realms of a number of famous institutions, but none of that is necessary in this case. Instead, replace its contents with this:

[libdefaults]
	default_realm = EXAMPLE.COM
	forwardable = true
	proxiable = true

[realms]
	EXAMPLE.COM = {
		kdc = klas2.example.com
		admin_server = klas.example.com
		database_module = openldap_ldapconf
	}

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

[dbdefaults]
	ldap_kerberos_container_dn = ou=krb5,dc=example,dc=com

[dbmodules]
	openldap_ldapconf = {
		db_library = kldap
		ldap_kdc_dn = cn=kdc-srv,ou=krb5,dc=example,dc=com
		ldap_kadmind_dn = cn=adm-srv,ou=krb5,dc=example,dc=com
		ldap_service_password_file = /etc/krb5kdc/service.keyfile
		ladap_conns_per_server = 5
	}

[logging]
	kdc = FILE:/var/log/krb5/kdc.log
	default = FILE:/var/log/krb5/kdc.log

See this section for a more detailed explanation of this file.

Note the absence of the ldap_servers statement from the list of openldap_ldapconf options. This is possible because the Kerberos daemons use IPC (Unix domain sockets) to connect to the LDAP back-end by default.

After /etc/krb5.conf has been saved, create the Kerberos log directory:

~# mkdir /var/log/krb5
~# _

To prevent the log file from growing too large, create a logrotate configuration file. Edit /etc/logrotate.d/krb5-kdc and give it the following contents:

/var/log/krb5/kdc.log {
        daily
        missingok
        rotate 7
        compress
        delaycompress
        notifempty
        postrotate
                /etc/init.d/krb5-kdc restart > /dev/null
        endscript
}

The various password stashes that were created previously on the provider − for the KDC database master key, the KDC service (for cn=kdc-srv) and the Kerberos administration server (cn=adm-srv) − are also required on this host. However, instead of creating them from scratch as was done before, simply copy them from the provider:

~# scp klas1:/etc/krb5kdc/s* /etc/krb5kdc/

Two files will be copied as a result: stash contains the KDC database master key, while service.keyfile contains the two service passwords.


9. Provider modifications

Switch over to the provider server, klas1.example.com, to make some changes there. Start by installing a package that will prevent a replication error from appearing in the syslog:

root@klas1:~# apt-get install sasl2-bin

A total of two packages are installed as a result, including one dependency:

db4.6-util             4.6.21-11                      Berkeley v4.6 Database Utilities
sasl2-bin              2.1.22.dfsg1-23+lenny1         Cyrus SASL - administration programs for SASL users database

Since debconf on klas1 is still set to Dialog/low, a question will appear. Answer it with its default setting:

Backup file name for /etc/sasldb2: /var/backups/sasldb2.bak

The installation process ends with a warning that saslauthd requires some tending to before it will start up automatically, but that can be ignored. All that is important here is that the install process creates a small database file, /etc/sasldb2, that slapd needs to have write access to so that certain error messages will not be generated. Next, make sure that the sasl group has access to the file:

root@klas1:~# chgrp sasl /etc/sasldb2
root@klas1:~# chmod 660 /etc/sasldb2
root@klas1:~# _

Then edit /etc/group on klas1 and add openldap to the sasl group:

sasl:x:45:openldap

Create a new LDAP entry that will be used to represent and authorize klas2 to read the entire DIT. Start by creating a file, ~/klas2.ldif, with the following contents:

dn: ou=consumers,dc=example,dc=com
ou: consumers
objectClass: organizationalUnit

dn: cn=klas2,ou=consumers,dc=example,dc=com
cn: klas2
objectClass: simpleSecurityObject
objectClass: organizationalRole
description: LDAP server2 replicator
userPassword: {CRYPT}*

Add these new LDAP entries to the DIT with:

root@klas1:~# kinit admin
Password for admin@EXAMPLE.COM: cerastes
root@klas1:~# ldapadd -f ~/klas2.ldif
SASL/GSSAPI authentication started
SASL username: admin@EXAMPLE.COM
SASL SSF: 56
SASL data security layer installed.
adding new entry "ou=consumers,dc=example,dc=com"

adding new entry "cn=klas2,ou=consumers,dc=example,dc=com"

root@klas1:~# _

Next, edit /etc/ldap/slapd.conf on klas1 and make a number of changes to it. First, add this extra authz-regexp stanza:

authz-regexp
     uid=host/([^/\.]+).example.com,cn=example.com,cn=gssapi,cn=auth
     cn=$1,ou=hosts,dc=example,dc=com

authz-regexp
     uid=ldap/([^/\.]+).example.com,cn=example.com,cn=gssapi,cn=auth
     cn=$1,ou=consumers,dc=example,dc=com

authz-regexp
     uid=([^,]+),cn=example.com,cn=gssapi,cn=auth
     uid=$1,ou=people,dc=example,dc=com

This is to map the GSSAPI name for klas2 to that of of the new LDAP entry, cn=klas2.

Add two new eq index directives:

index           objectClass eq
index           uid eq
index           krbPrincipalName eq,pres,sub
index           entryUUID eq
index           entryCSN eq

Then modify the ACLs to ensure that cn=klas2 has read access to everything in the database:

access to attrs=userPassword,shadowLastChange
        by dn="cn=admin,dc=example,dc=com" write
	by dn.one="ou=consumers,dc=example,dc=com" read
        by anonymous auth
        by * none

access to dn.subtree="ou=krb5,dc=example,dc=com"
        by dn="cn=admin,dc=example,dc=com" write
	by dn.one="ou=consumers,dc=example,dc=com" read
        by dn="cn=adm-srv,ou=krb5,dc=example,dc=com" write
        by dn="cn=kdc-srv,ou=krb5,dc=example,dc=com" read
        by * none

access to attrs=loginShell
        by dn="cn=admin,dc=example,dc=com" write
        by self write
        by users read
        by * none

access to dn.base=""
        by * read

access to *
        by dn="cn=admin,dc=example,dc=com" write
        by users read
        by * none

This ensures that all entries directly under ou=consumers will have full read access to the DIT.

Lastly, add these four lines to the end of the first database section to load, activate and configure the Sync Provider overlay:

access to *
        by dn="cn=admin,dc=example,dc=com" write
        by users read
        by * none

moduleload      syncprov
overlay         syncprov

syncprov-checkpoint 100 10
syncprov-sessionlog 100

Because the changes to slapd.conf on klas1 include new index directives, it is not only necessary to restart slapd, but also to reindex the database. Since it is best to run the slapindex command as the openldap user, first make this possible by altering the following line (that may not have the same UID and GID numbers) in the /etc/passwd file:

openldap:x:105:107:OpenLDAP Server Account,,,:/var/lib/ldap:/bin/sh

Now stop the LDAP service, regenerate the database indices as the openldap user, and restart the LDAP service:

root@klas1:~# /etc/init.d/krb5-admin-server stop
root@klas1:~# /etc/init.d/krb5-kdc stop
root@klas1:~# /etc/init.d/slapd stop
Stopping OpenLDAP: slapd.
root@klas1:~# su -c /usr/sbin/slapindex openldap
root@klas1:~# /etc/init.d/slapd start
Starting OpenLDAP: slapd.
root@klas1:~# /etc/init.d/krb5-kdc start
root@klas1:~# /etc/init.d/krb5-admin-server start
root@klas1:~# _

10. Kstart

Return to klas2. To keep its copy of the LDAP database in sync, the consumer must contact the provider and authenticate itself just like any other client. In other articles it has been shown how to do this with a simple bind and a password, but in this case Kerberos will be used to take care of both slapd consumer authentication to the provider and encryption of the entire replication process. To make this possible, an initial Kerberos ticket (a TGT) must be obtained automatically on behalf of the openldap user, which owns the slapd process, and it must be renewed regularly. One way to do this is to run kinit -k with a cron job, but a better solution is to use a modified version of kinit, called k5start. Install it with:

~# apt-get install kstart

This is the only package that gets installed as a result:

kstart                   3.14-1                     Kerberos kinit supporting AFS and ticket refreshing

To configure it, just add this line to the end of the /etc/inittab file to start running k5start in the background soon after the system boots up:

KS:2345:respawn:/usr/bin/k5start -U -f /etc/krb5.keytab -K 10 -l 24h -k /tmp/krb5cc_105 -o openldap

A number of options have been used for this command:

-U Determine the principal to authenticate based on the first entry in the Kerberos keytab file. Must be used with the -f option.
-f /etc/krb5.keytab Specifies the full path of the Kerberos keytab file.
-K 10 Reawaken the daemon every 10 minutes to check if the ticket needs to be renewed.
-l 24h Set the ticket lifetime to 24 hours (to match the actual ticket lifetime used in this example).
-k /tmp/krb5cc_105 Use the file /tmp/krb5cc_105 as the ticket cache. The number at the end of the file name must match the UID (105 in this example) of the user on behalf of whom the ticket is maintained (see option -o).
-o openldap The name of the user account that is to become the owner of the ticket cache file (see option -k).

After saving this modification to /etc/inittab, start k5start for the first time by forcing init to reload its configuration file:

~# kill -HUP 1

A new ticket cache file, /tmp/krb5cc_105, should be created almost immediately as a consequence.


11. sasldb2

Install a package, the sole purpose of which is to prevent a certain error from appearing in the syslog:

~# apt-get install sasl2-bin

A total of two packages are installed as a result, including one dependency:

db4.6-util           4.6.21-11                       Berkeley v4.6 Database Utilities
sasl2-bin            2.1.22.dfsg1-23+lenny1          Cyrus SASL - administration programs for SASL users database

The sasldb2 database file is installed here for the same reasons as on klas1. Begin by making sure that the sasl group has access to the file:

~# chgrp sasl /etc/sasldb2
~# chmod 660 /etc/sasldb2
~# _

Then edit /etc/group and add openldap to the sasl group:

sasl:x:45:openldap

12. Slapd kerberization

This step is about kerberizing OpenLDAP. A number of requirements have already been met, but there is more. First, install this one package:

~# apt-get install libsasl2-modules-gssapi-mit

Only one package is installed as a result with no dependencies:

libsasl2-modules-gssapi-mit       2.1.22.dfsg1-23+lenny1        Cyrus SASL - pluggable authentication modules (GSSAPI)

Change the permissions and ownership of the Kerberos service keytab file to allow slapd to read it:

~# chmod 640 /etc/krb5.keytab
~# chown root.openldap /etc/krb5.keytab
~# _

Next, three different files must be modified. First, edit /etc/default/slapd and and uncomment a line near the end of the file that will export the location of the Kerberos system keytab file as a variable:

export KRB5_KTNAME=/etc/krb5.keytab

Edit /etc/ldap/ldap.conf and add the following line, which specifies the authentication mechanism, to the end of the file:

SASL_MECH GSSAPI

Then, edit /etc/ldap/slapd.conf and add these lines to the end of the Global section (before any database definitions):

tool-threads 1

authz-regexp
     uid=admin,cn=example.com,cn=gssapi,cn=auth
     cn=admin,dc=example,dc=com

authz-regexp
     uid=host/([^/\.]+).example.com,cn=example.com,cn=gssapi,cn=auth
     cn=$1,ou=hosts,dc=example,dc=com

authz-regexp
     uid=([^,]+),cn=example.com,cn=gssapi,cn=auth
     uid=$1,ou=people,dc=example,dc=com

sasl-realm      EXAMPLE.COM

All of these changes were also made on the provider server, klas1.



13. Syncrepl

Continue to edit /etc/ldap/slapd.conf, this time to enable the replication process. Start by adding two more eq index entries:

index           objectClass eq
index           uid eq
index           krbPrincipalName eq,pres,sub
index           entryUUID eq
index           entryCSN eq

These two eq indexes will accelerate the replication process.

Then add this replication stanza to the end of the first database section:

access to *
        by users read
        by * none

syncrepl rid=123
        provider=ldap://klas.example.com:389/
        type=refreshAndPersist
        retry="60 30 300 +"
        searchbase="dc=example,dc=com"
        bindmethod=sasl
        saslmech=gssapi

With the refreshAndPersist replication type, any changes made to the provider database are immediately sent to the consumer. Note that the provider's alias, ldapks, is used here, so if the OpenLDAP provider is ever moved to a different host, only the alias will need to be changed − not the configurations of the various consumers.

Alternatively, in case a more bandwidth-friendly solution is desired, the refreshOnly replication strategy can be used instead:

syncrepl rid=123
        provider=ldap://klas.example.com:389/
        type=refreshOnly
        interval=00:00:05:00
        searchbase="dc=example,dc=com"
        bindmethod=sasl
        saslmech=gssapi

Usually, complete replication of the provider's copy of the OpenLDAP database is only possible if specific access rules are added to the provider's slapd.conf to ensure that each consumer server has read access to everything. However, in this case it is currently unnecessary to change the provider's ACLs, because other than a few unnecessary passwords, all users have complete access to the DIT anyway.


14. Referrals

Still editing /etc/ldap/slapd.conf, add a referral to the end of the file, below the syncrepl stanza, to inform clients where to find the provider when they need to make changes to the LDAP database:

        bindmethod=sasl
        saslmech=gssapi

updateref       ldap://klas.example.com:389/

Finally, since some LDAP client applications do not understand referrals, implement the chain overlay to allow slapd to chase referrals on behalf of such clients by adding the following lines to the global section of slapd.conf, before any database definitions:

sasl-realm      EXAMPLE.COM

moduleload              back_ldap
overlay                 chain

chain-uri               ldap://klas.example.com:389/
chain-rebind-as-user    TRUE
chain-idassert-bind     bindmethod=sasl
                        saslmech=gssapi
                        mode=self
chain-return-error      TRUE

Having saved all of the previous changes to /etc/slapd.conf, stop the LDAP service, delete the now-redundant local database, and restart the service. This will cause the consumer to synchronize its database with the provider for the first time:

~# /etc/init.d/slapd stop
Stopping OpenLDAP: slapd.
~# rm /var/lib/ldap/*
~# /etc/init.d/slapd start
Starting OpenLDAP: slapd.
~# _

If the original copy of the local database on klas2 is not deleted, its two existing entries − the domain component and the admin user (with password cercobombus) − will not be replaced with those of the provider, even though the rest of the DIT will be synchronized.

If everything works as expected, it should now be possible to run the slapcat command on both the consumer and the provider and verify that, in both cases, the entire output is exactly the same.


15. Kerberos server start

Start the Kerberos admin and KDC servers for the first time:

~# /etc/init.d/krb5-kdc start
~# _

If there are no errors, run the following command to verify that the new MIT Kerberos V master server is indeed available on the network:

~# nmap -sU klas2.example.com.

Note the trailing dot! This should be among the results:

PORT     STATE SERVICE
88/udp   open|filtered kerberos-sec
750/udp  open|filtered kerberos
4444/udp open|filtered krb524

16. Authentication test

Run some tests. First try a simple unauthenticated (-x) LDAP query:

~# ldapsearch -x -LLL cn=klas2
No such object (32)
~# _

As on klas1, this no longer works. The authenticated version will also give an error:

~# ldapsearch -LLL cn=klas2
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Local error (-2)
~# _

Acquire a Kerberos ticket for the admin user (password cerastes):

~# kinit admin
Password for admin@EXAMPLE.COM: cerastes
~# _

A verification of the ticket should show a success:

~# klist -5
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: admin@EXAMPLE.COM

Valid starting     Expires            Service principal
03/04/10 15:37:46  03/05/10 15:37:43  krbtgt/EXAMPLE.COM@EXAMPLE.COM
03/04/10 15:37:49  03/05/10 15:37:43  ldap/klas2.example.com@EXAMPLE.COM
~# _

Now the authenticated version of the query should also work:

~# ldapsearch -LLL cn=klas2
SASL/GSSAPI authentication started
SASL username: admin@EXAMPLE.COM
SASL SSF: 56
SASL data security layer installed.
dn: cn=klas2,ou=consumers,dc=example,dc=com
cn: klas2
objectClass: simpleSecurityObject
objectClass: organizationalRole
description: LDAP server2 replicator
userPassword:: e0NSWVBUfSo=

~# _

17. Proxy authorization

Before the chaining configuration added in step 14 will work, more changes first have to be made to the OpenLDAP provider server, klas1.example.com. What is required is something called SASL proxy authorization. With this mechanism it is possible to allow an authenticated user, such as the consumer server in this example, to assume the identity of other users and use that to relay their write requests on to the provider server. The ability to assume another user's identity is important, as it would otherwise not be possible to enforce existing access rules.

Two changes are needed to enable proxy authorization. First, the cn=klas2 LDAP object must be modified to include the authzTo attribute, which will allow it to act as an authorization proxy for certain users. Second, an authz-policy directive must be added to the slapd.conf file. Start by creating an LDIF file on the provider server, called ~/klas2-mod.ldif, with the following contents:

dn: cn=klas2,ou=consumers,dc=example,dc=com
changetype: modify
add: authzTo
authzTo: dn.regex:^uid=[^,]+,ou=people,dc=example,dc=com$
authzTo: dn.exact:cn=admin,dc=example,dc=com
-

The authzTo attribute is a source rule that determines which user identities it is allowed to assume; in this case its value is a regular expression that matches all uid objects in the ou=people,dc=example,dc=com container.

Run the following command to apply this modification:

root@klas1:~# ldapmodify -f ~/klas2-mod.ldif
SASL/GSSAPI authentication started
SASL username: admin@EXAMPLE.COM
SASL SSF: 56
SASL data security layer installed.
modifying entry "cn=klas2,ou=consumers,dc=example,dc=com"

root@klas1:~# _

Next, edit /etc/ldap/slapd.conf on klas1 and add this line to the end of the Global directives section:

sasl-realm      EXAMPLE.COM

authz-policy    to

This statement enables proxy authorization using rules associated with the authzTo attribute of the authentication DN (in this case cn=klas2). Without this, the authzTo attribute that was added to the cn=klas2 entry would be ignored.

Having made these changes to /etc/slapd.conf, save them and restart the LDAP service:

root@klas1:~# /etc/init.d/slapd restart
Stopping OpenLDAP: slapd.
Starting OpenLDAP: slapd.
root@klas1:~# _

18. Proxy auth test

This last step will test whether the proxy authorization actually works. This is easily done on the consumer server by attempting to make a minor modification to one entry or another. For instance, try changing the description for the cn=klas2 entry. Start by created a new file, ~/klas2-mod2.ldif, with the following contents:

dn: cn=klas2,ou=consumers,dc=example,dc=com
changetype: modify
replace: description
description: OpenLDAP consumer server
-

Then apply this change with the ldapmodify command:

~# ldapmodify -f ~/klas2-mod2.ldif
SASL/GSSAPI authentication started
SASL username: admin@EXAMPLE.COM
SASL SSF: 56
SASL data security layer installed.
modifying entry "cn=klas2,ou=consumers,dc=example,dc=com"

~# _

That looked like a success. Over on klas1, this is what appeared in the syslog as a result:

klas1 slapd[2694]: conn=1 fd=18 ACCEPT from IP=192.168.2.47:36466 (IP=0.0.0.0:389)
klas1 slapd[2694]: conn=1 op=0 BIND dn="" method=163
klas1 slapd[2694]: conn=1 op=0 RESULT tag=97 err=14 text=SASL(0): successful result: 
klas1 slapd[2694]: conn=1 op=1 BIND dn="" method=163
klas1 slapd[2694]: conn=1 op=1 RESULT tag=97 err=14 text=SASL(0): successful result: 
klas1 slapd[2694]: conn=1 op=2 BIND dn="" method=163
klas1 slapd[2694]: conn=1 op=2 BIND authcid="ldap/klas2.example.com@EXAMPLE.COM" authzid="ldap/klas2.example.com@EXAMPLE.COM"
klas1 slapd[2694]: conn=1 op=2 BIND dn="cn=klas2,ou=consumers,dc=example,dc=com" mech=GSSAPI sasl_ssf=56 ssf=56
klas1 slapd[2694]: conn=1 op=2 RESULT tag=97 err=0 text=
klas1 slapd[2694]: conn=1 op=3 PROXYAUTHZ dn="cn=admin,dc=example,dc=com"
klas1 slapd[2694]: conn=1 op=3 MOD dn="cn=klas2,ou=consumers,dc=example,dc=com"
klas1 slapd[2694]: conn=1 op=3 MOD attr=description
klas1 slapd[2694]: conn=1 op=3 RESULT tag=103 err=0 text=

This confirms that klas2 is using its Kerberos ID, ldap/klas2.example.com@EXAMPLE.COM, which is then translated by the authz-regexp statement on klas1 to cn=klas2, which is then authorized to act as a proxy for cn=admin, which is in turn authorized to modify the cn=klas2 entry.

For another confirmation of success, a search for cn=klas2 should show that this entry has indeed been modified:

~# ldapsearch -LLL cn=klas2
SASL/GSSAPI authentication started
SASL username: admin@EXAMPLE.COM
SASL SSF: 56
SASL data security layer installed.
dn: cn=klas2,ou=consumers,dc=example,dc=com
cn: klas2
objectClass: simpleSecurityObject
objectClass: organizationalRole
userPassword:: e0NSWVBUfSo=
description: OpenLDAP consumer server

~# _

19. Debconf reconfig

From this point on, a more detailed level of questioning will be required from debconf. To achieve this, run the following command:

~# dpkg-reconfigure debconf

Answer the questions as follows:

Interface to use: Dialog
Ignore questions with a priority less than: low

20. AFS kernel module

The objective here is to build and install the OpenAFS kernel module from source. However, since this host is physically identical to the previously installed machine, klas1, save time by copying the already compiled package from that system to this one:

~# scp klas1:/usr/src/openafs-modules*.deb /usr/src/

Following that, install the package:

~# dpkg -i /usr/src/openafs-modules*.deb

After it has been built and installed, test the OpenAFS kernel module by loading it:

~# modprobe openafs

Again, this it what it looks like when the module has been loaded:

~# lsmod |grep afs
openafs               473948  0 
~#

21. OpenAFS client install

Install the OpenAFS client. Now install these two packages:

~# apt-get install openafs-{client,krb5}

Only these two packages are installed as a result:

openafs-client                1.4.7.dfsg1-6+lenny2                 AFS distributed filesystem client support
openafs-krb5                  1.4.7.dfsg1-6+lenny2                 AFS distributed filesystem Kerberos 5 integration

Following the installation process, debconf will ask a few questions regarding the openafs-client package. Answer them as follows:

AFS cell this workstation belongs to: example.com
Size of AFS cache in kB: 50000
Run Openafs client now and at boot? No
Look up AFS cells in DNS? Yes
Encrypt authenticated traffic with AFS fileserver? No
Dynamically generate the contents of /afs? Yes
Use fakestat to avoid hangs when listing /afs? Yes
DB server host names for your home cell: klas1 klas2

Regarding the AFS cache, the default size is about 50 MB and is located in the /var/cache/openafs/ directory. Often, the cache is increased to around 512 MB, but usually less than 1 GB; larger cache sizes may lengthen the startup time, as all files within the cache must be prechecked with the servers. It is vital that OpenAFS is never in danger of running out of cache space, since it is not designed to handle such situations gracefully. A requirement is also that an ext2 or ext3 file system is used for the cache directory; a file containing such a file system, or a dedicated partition can be used for this purpose, but its even possible to use a memory-based cache, which offers signifigant performance benefits.


22. OpenAFS server install

To install the OpenAFS server, start by copying some vital information from klas1:

~# scp -r klas1:/etc/openafs/server /etc/openafs
root@klas1's password: 
CellServDB                                   100%   38     0.0KB/s   00:00
CellServDB.old                               100%   38     0.0KB/s   00:00
KeyFile                                      100%  100     0.1KB/s   00:00
UserList                                     100%    6     0.0KB/s   00:00
ThisCell                                     100%    8     0.0KB/s   00:00
~# _

These files include the AFS KeyFile, which must be exactly the same on all of the AFS servers that belong to the same cell.

Now install the server packages:

~# apt-get install openafs-{fileserver,dbserver}

These are also the only two packages that are installed as a result:

openafs-dbserver              1.4.7.dfsg1-6+lenny2                 AFS distributed filesystem database server
openafs-fileserver            1.4.7.dfsg1-6+lenny2                 AFS distributed filesystem file server

One question must be answered for the openafs-fileserver package:

Cell this server serves files for: example.com

23. AFS partition

OpenAFS is usually set up to work with dedicated partitions of which each server can maintain up to 256. These partitions are associated with mount points just below the root that follow a particular naming convention, /vicepXX/, where XX can be any letter, or two-letter combination. In this exercise, a separate partition, /dev/hdb1, will be formatted with the ext3 file system and mounted at /vicepa/.

Actually, in cases where a separate partition is not available, it is also possible for OpenAFS to simply use a /vicepXX/ directory in the root partition. This is because OpenAFS does not require any particular low-level format for its partitions. AFS partitions can therefore be explored with ordinary UNIX tools, although the data stored therein is structured in a way that is only meaningful to OpenAFS.

Assuming a partition has already been created on the disk, format it with:

~# mkfs.ext3 /dev/hdb1
mke2fs 1.41.3 (12-Oct-2008)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
262144 inodes, 1048564 blocks
52428 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1073741824
32 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736

Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 26 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
~# _

Then edit /etc/fstab and add this line to the end of the file:

/dev/hdb1       /vicepa         ext3    defaults        0       0

Now create the mount point and mount the new partition:

~# mkdir /vicepa ; mount /vicepa/
~# _

24. Adding klas2 to the cell

To add the new server to the existing AFS cell, a series of actions will have to be taken on both the new server and the existing server(s) (in this case only klas1). Start by creating a file server instance on klas2:

klas2:~# bos create klas2.example.com fs fs \
	-cmd '/usr/lib/openafs/fileserver -p 23 -busyat 600 -rxpck 400 -s 1200 -l 1200 -cb 65535 -b 240 -vc 1200' \
	-cmd /usr/lib/openafs/volserver \
	-cmd /usr/lib/openafs/salvager \
	-localauth
klas2:~# _

Note that the first -cmd, for fileserver, is between single quotes and may not contain any backslashes.

Confirm that this worked:

klas2:~# bos status localhost -noauth
Instance fs, currently running normally.
    Auxiliary status is: file server running.
klas2:~# _

Since klas2 is also meant to be an AFS database server, the next task is to ensure that all of the servers know this. Start on klas1:

klas1:~# bos addhost -server klas1.example.com \
	-host klas2.example.com -localauth
klas1:~# _

After that, the idea is to do the same for klas2, but first edit /etc/hosts on that host and comment out the entry for klas2:

#127.0.1.1      klas2.example.com    klas2

Now run the bos addhost command on klas2:

klas2:~# bos addhost -server klas2.example.com \
	-host klas2.example.com -localauth
klas2:~# _

Following that, restart the ptserver and vlserver instances on klas1:

klas1:~# bos restart -server klas1.example.com \
	-instance ptserver -localauth
klas1:~# bos restart -server klas1.example.com \
	-instance vlserver -localauth
klas1:~# _

After performing this operation, pause for a few moments to allow enough time for the voting process before moving on to any other existing servers. Then check the status on klas1:

klas1:~# bos status localhost -noauth
Instance ptserver, currently running normally.
Instance vlserver, currently running normally.
Instance fs, currently running normally.
    Auxiliary status is: file server running.
klas1:~# _

After the ptserver and vlserver instances have been restarted on klas1 and possibly any other existing servers, proceed to create them on the new server:

klas2:~# bos create -server klas2.example.com \
	-instance ptserver -type simple -cmd /usr/lib/openafs/ptserver \
	-localauth
klas2:~# bos create -server klas2.example.com \
	-instance vlserver -type simple -cmd /usr/lib/openafs/vlserver \
	-localauth
klas2:~# _

Check that both processes are up and running:

klas2:~# bos status localhost -noauth
Instance fs, currently running normally.
    Auxiliary status is: file server running.
Instance ptserver, currently running normally.
Instance vlserver, currently running normally.
klas2:~# _

25. AFS client & test

Now that the OpenAFS server is up and running, enable the OpenAFS client. It was installed much earlier, but configured to not start up automatically. Change that by editing /etc/openafs/afs.conf.client and changing the following line:

AFS_CLIENT=true

Now restart the client:

~# /etc/init.d/openafs-client restart
Stopping AFS services: afsd openafs.
Starting AFS services: openafs afsd.
afsd: All AFS daemons started.
~# _

After the AFS client has been started, check out the contents of the new AFS volume in the /afs/ directory:

~# ls /afs | head
1ts.org/
acm-csuf.org/
acm.uiuc.edu/
ams.cern.ch/
andrew.cmu.edu/
anl.gov/
asu.edu/
athena.mit.edu/
atlass01.physik.uni-bonn.de/
atlas.umich.edu/
~# ls /afs | wc -l
188
~# _

26. See also
27. Further reading
  • Eastlake D, Panitz A. 1999. RFC2606 − Reserved Top Level DNS Names. The Internet Society. HTML at the Internet FAQ Archives.
  • Hodges J, Morgan R. 2002. RFC3377 − Lightweight Directory Access Protocol (v3): Technical Specification. The Internet Society. HTML at the Internet FAQ Archives.
  • Kohl J, Neuman C. 1993. RFC1510 − The Kerberos Network Authentication Service (V5). HTML at the Internet FAQ Archives.
  • Linn J. 2000. RFC2743 − Generic Security Service Application Program Interface Version 2, Update 1. The Internet Society. HTML at the Internet FAQ Archives.
  • Myers J. 1997. RFC2222 − Simple Authentication and Security Layer (SASL). The Internet Society. HTML at the Internet FAQ Archives.
  • Wahl M, Howes T, Kille S. 1997. RFC2251 − Lightweight Directory Access Protocol (v3). The Internet Society. HTML at the Internet FAQ Archives.
  • Wilkinson S. 2008. OpenAFS, FOSDEM 2008. Video (15:30 minutes) at YouTube.
  • Wray J. 2000. RFC2744 − Generic Security Service API Version 2 : C-bindings. The Internet Society. HTML at the Internet FAQ Archives.
  • Yeong W, Howes T, Kille S. 1993. RFC1487 − X.500 Lightweight Directory Access Protocol. The Internet Society. HTML at the Internet FAQ Archives.

28. Sources
  • Campbell R. 1998. Managing AFS: The Andrew File System. Prentice Hall. ISBN 0-13-802729-3. 479 pp.
  • Carter G. 2003. LDAP System Administration. O'Reilly & Associates, Inc. ISBN 1-56592-491-6. 294 pp.
  • Garman J. 2003. Kerberos, The Definitive Guide. O'Reilly & Associates, Inc. ISBN-13 978-0-596-00403-3. 253 pp.
  • Massachusetts Institute of Technology. 1985-2007. Kerberos V5 System Administrator's Guide. HTML at the Massachusetts Institute of Technology (MIT). See section 6: Configuring Kerberos with OpenLDAP back-end.
  • Milicchio F, Gehrke WA. 2007. Distributed Services with OpenAFS. Springer-Verlag. ISBN-13 978-3-540-36633-1. 395 pp.
  • Ocelic D. 2006-2010. Debian GNU: Setting up MIT Kerberos 5. HTML at Spinlock Solutions.
  • Ocelic D. 2006-2010. Debian GNU: Setting up OpenAFS 1.4.x. HTML at Spinlock Solutions.
  • Ocelic D. 2006-2010. Debian GNU: Setting up OpenLDAP. HTML at Spinlock Solutions.
  • OpenAFS. 2000-2009. Documentation. HTML at OpenAFS.
  • Ubuntu documentation. Ubuntu 9.04. Ubuntu Server Guide, Network Authentication, Kerberos and LDAP. HTML at the Ubuntu 9.04 Server Guide.


Last modified: 2012-08-24, 18:36

©2003-2014 RJ Systems. Permission is granted to copy, distribute and/or modify the
content of this page under the terms of the OpenContent License, version 1.0.