RJ Systems
Linux System Administration
Home Tech Linux Links Consulting







Valid XHTML 1.0!

Valid CSS!

IPv6 test

Integrated Kerberos-OpenLDAP-OpenAFS client

Introduction

This article builds on previous ones in which provider and consumer servers, klas1.example.com and klas2.example.com, were installed and configured, both running MIT Kerberos V, OpenLDAP and OpenAFS. The aim here is to set up a client machine that will use the Kerberos, LDAP and AFS services offered by those hosts to respecitively authenticate and authorize users to log into the client and use AFS for their home directories and other file access. The system also relies heavily on timestamps, so reasonably accurate time synchronization among all participating hosts is essential.

In this example, client software for OpenLDAP, MIT Kerberos V and OpenAFS is installed on a host running Debian 5.0 (lenny). If followed properly, the step-by-step process should produce a new client machine that will make use of all of these resources.

Before the relevant installation procedures can begin, it will first be necessary to install Debian lenny on a new host called klac1.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

After installing them, edit /etc/ntp.conf so that the new host synchronizes to a common NTP server (preferably a local one) and edit /etc/default/ntpdate to do the same. Now the installation process for the new Kerberos-LDAP-AFS client 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 klas2.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. Realm config file

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 = klas1.example.com
                kdc = klas2.example.com
                admin_server = klas.example.com
        }

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

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

Regarding the list of KDCs that are specified here, it is often recommended to use a predetermined set of DNS hostname aliases (CNAME records) to refer to the Kerberos servers on a network. However, it is also possible to omit the KDC entries in /etc/krb5.conf and instead rely on SRV DNS resource records to do the same job. See DNS discovery for MIT Kerberos V for information on how to do that.


3. Host princ & keytab

Use kadmin to create a host principal and a local 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 host/klac1.example.com
WARNING: no policy specified for host/klac1.example.com@EXAMPLE.COM;
defaulting to no policy
Principal "host/klac1.example.com@EXAMPLE.COM" created.
kadmin:  ktadd host/klac1.example.com
Entry for principal host/klac1.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 host/klac1.example.com with kvno 3, encryption type
ArcFour with HMAC/md5 added to keytab 
WRFILE:/etc/krb5.keytab.
Entry for principal host/klac1.example.com with kvno 3, encryption type
Triple DES cbc mode with HMAC/sha1 added to keytab
WRFILE:/etc/krb5.keytab.
Entry for principal host/klac1.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.


4. 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

5. LDAP client install

Run the following command to test if the previously installed OpenLDAP 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, continue by installing these five packages:

~# apt-get install ldap-utils libnss-ldap libpam-ldap nscd \
   libsasl2-modules-gssapi-mit

As a result, six packages are installed, including one dependency:

ldap-utils                       2.4.11-1+lenny1             OpenLDAP utilities
libnss-ldap                      261-2.1                     NSS module for using LDAP as a naming service
libpam-ldap                      184-4.2                     Pluggable Authentication Module for LDAP
libsasl2-modules                 2.1.22.dfsg1-23+lenny1      Cyrus SASL - pluggable authentication modules
libsasl2-modules-gssapi-mit      2.1.22.dfsg1-23+lenny1      Cyrus SASL - pluggable authentication modules (GSSAPI)
nscd                             2.7-18lenny2                GNU C Library: Name Service Cache Daemon

During the installation procedure, certain questions will be asked about two of these packages, first, about libnss-ldap. Answer them as follows:

LDAP server Uniform Resource Identifier: ldap://klas1.example.com/ ldap://klas2.example.com/
Distinguished name of the search base: dc=example,dc=com
LDAP version to use: 3
Does the LDAP database require login? No
Special LDAP privileges for root? No
Make the configuration file readable/writeable by its owner only? No

NB: Regarding the question of which LDAP server to use, this field supports mutiple server URIs.

These six questions are immediately followed by three more regarding libpam-ldap. Answer them as follows:

Make local root database admin: No
Does the LDAP database require login?: No
Local crypt to use when changing passwords: crypt

6. Kstart

It is one thing to set up a host that requires users to authenticate with Kerberos, but it is another to arrange for the host itself to use LDAP to search for information about new users in order to set up home directories for them as they log in. This lookup is performed by libnss-ldap; a package that will be installed shortly. However, libnss-ldap will only be able to do this if the host first authenticates automatically, using its Kerberos host key, and subsequently creates a ticket cache file (with a TGT) that libnss-ldap can use. The question is then how to achieve this. One way to do it 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

Four 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).

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

~# kill -HUP 1

Immediately afterwards, the Kerberos ticket cache file for root, /tmp/krb5cc_0, should appear.

NB: If the client is configured to authenticate to a Kerberos slave KDC only, then it may be necessary to force replication of the Kerberos database from the master to the slave before k5start can receive an initial Kerberos ticket (TGT).

To kerberize libnss-ldap, edit /etc/libnss-ldap.conf and add these three lines to the end of the file:

use_sasl        on
sasl_mech       gssapi
krb5_ccname	FILE:/tmp/krb5cc_0

This will instruct libnss-ldap (and thus nscd) to use SASL and GSSAPI, as well where to find the Kerberos ticket cache for the klac1 host principal. The ticket cache file is only accessible by root, but this is not a problem, since nscd runs as root anyway.

Following this last edit, if the machine has not already been rebooted, restart nscd now:

~# /etc/init.d/nscd restart
Restarting Name Service Cache Daemon: nscd.
~# _

7. ldap.conf

Edit /etc/ldap/ldap.conf and add these three lines to the end of the file:

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

SASL_MECH GSSAPI

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


8. nsswitch.conf

As is mentioned during the install procedure for libnss-ldap, the /etc/nsswitch.conf configuration file needs to be edited before authentication and authorization via LDAP can work. These are the necessary changes that must be made to it:

passwd:         compat ldap
group:          compat ldap
shadow:         compat ldap

However, there is an irritating bug in this version of libnss_ldap that manifests itself during the boot process. It causes the host to attempt to contact the LDAP server before the local network interface has been activated, which results in something like a minute's worth of errors about libnss_ldap not being able to contact the LDAP server − very tedious indeed.

There are at least two solutions to this problem. The first is simple: it still leads to a series of errors during the boot process, but they pass much more quickly. The second is a bit more involved, but under most circumstances prevents any errors from occurring at all. First, the simple solution. Basically, all that is necessary is to edit /etc/libnss-ldap.conf and add this single line:

#bind_policy hard

bind_policy soft

Then, restart the Name Service Cache Daemon:

~# /etc/init.d/nscd restart
Restarting Name Service Cache Daemon: nscd.
~# _

If this solution is employed, skip the rest and move on to the next step.

The second solution to this problem is suggested in a Debian bug report and involves maintaining two extra copies of /etc/nsswitch.conf: one version that includes support for LDAP and one that does not. The LDAP version is used to overwrite the original just after the network interface is activated, while the non-LDAP version is used to overwrite the original just before the interface is deactivated. To implement this workaround, first create the two copies of the existing /etc/nsswitch.conf:

~# cp /etc/nsswitch.conf /etc/nsswitch.conf.org
~# cp /etc/nsswitch.conf /etc/nsswitch.conf.ldap

Assuming that the earlier described changes to /etc/nsswitch.conf have already been made, edit one of its copies, /etc/nsswitch.conf.org, and remove "ldap" again from the same three lines, thereby returning it to the original state of its parent:

passwd:         compat
group:          compat
shadow:         compat

Create two scripts that will overwrite the active version of nsswitch.conf.ldap with the LDAP-enabled version or the original. The first one is called /usr/local/bin/nsswitch-org and has the following contents:

#!/bin/sh

/bin/cp /etc/nsswitch.conf.org /etc/nsswitch.conf

exit 0

The second script, /usr/local/bin/nsswitch-ldap, is just a little different:

#!/bin/sh

/bin/cp /etc/nsswitch.conf.ldap /etc/nsswitch.conf

exit 0

Do not forget to make these two new scripts executable:

~# chmod 750 /usr/local/bin/nsswitch-*

Now add two lines to /etc/network/interfaces, for post-up and post-down, to run these scripts after the interface is activated and before it is deactivated. In this example, the interface is eth0 and uses DHCP:

iface eth0 inet dhcp
	post-up /usr/local/bin/nsswitch-ldap
	pre-down /usr/local/bin/nsswitch-org

This is only a workaround and is not perfect. In particular, if the host is not shut down properly so that the /usr/local/bin/nsswitch-ldap script has not had a chance to execute, the aforementioned irritating errors will occur during the next bootup. This cannot be helped, because the problem with libnss_ldap.so occurs before the root file system is mounted read/write, making it impossible to implement any solution that might involve overwriting nsswitch.conf with a non-LDAP version before the event takes place.

At this point there are various ways to get this script-swapping process going, but the easiest is probably just to reboot:

~# reboot

This way, no LDAP errors will occur when the system starts up again and afterwards the configuration of the host can continue.


9. AFS kernel module

At this point it would be necessary to build and install the OpenAFS kernel module from source. If klac1 were to require a Linux kernel that is different from the one used on klas1, then there would be no choice but to do that. However, to avoid repetition, it is assumed that the kernel used here is the same, which allows time to be saved by using the already compiled package from that system on this one. So, simply copy the package from klas1:

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

Following that, install it:

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

After that, 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 
~#

10. OpenAFS client install

Install the OpenAFS client. Now install these three packages:

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

Only these three 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
libpam-afs-session            1.7-1                    PAM module to set up a PAG and obtain AFS tokens

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? Yes
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.

Regarding the list of AFS DB server host names that are specified here, one strategy to manage large numbers of client machines would be to use a predetermined set of DNS hostname aliases (CNAME records) to refer to the AFS DB servers on a network. However, it is also possible to omit the AFS DB entries and instead rely on SRV DNS resource records to do the same job. See DNS discovery for OpenAFS for information on how to do that.


11. PAM configuration

Altering the client machine's Linux-PAM configuration will make it possible for users to authenticate using either a Unix or a Kerberos password. However, as PAM is both a relatively complex subject and a recurring theme, it was decided to create a dedicated page for it. Those unfamiliar with its workings are advised to read it. Otherwise, make the modifications described below, which are followed by a few explanations.

Edit /etc/pam.d/common-auth and change it to:

auth        sufficient    pam_unix.so          nullok_secure
auth        sufficient    pam_krb5.so          use_first_pass
auth        optional      pam_afs_session.so   program=/usr/bin/aklog
auth        required      pam_deny.so

Edit /etc/pam.d/common-account and change it to:

account     sufficient    pam_unix.so
account     sufficient    pam_krb5.so
account     required      pam_ldap.so
account     required      pam_deny.so

Edit /etc/pam.d/common-password and change it to:

password    sufficient    pam_unix.so          nullok obscure md5
password    sufficient    pam_krb5.so          use_first_pass
password    required      pam_deny.so

Edit /etc/pam.d/common-session and change it to:

session     optional      pam_unix.so
session     optional      pam_krb5.so
session     optional	  pam_ldap.so
session     optional      pam_afs_session.so   program=/usr/bin/aklog

In this modified PAM configuration, three new modules are introduced:

pam_krb5.so Provides authentication and also account, session and password management against Kerberos servers.
pam_afs_session.so Executes aklog to create an AFS kernel-based token based on the Kerberos ticket.
pam_deny.so Always denies access. Used as a default for security purposes.
pam_ldap.so Provides authorization via LDAP servers.

In /etc/pam.d/common-auth, an argument is used for the pam_krb5.so module: use_first_pass. This forces it to use a password that was used for the previous module in the stack so that it does not prompt the user. The module will fail only if the password is absent or invalid.

Using sufficient instead of required for pam_krb5.so and pam_unix.so in the first three of these configuration files creates a situation where success is possible if only one of the two modules succeeds. However, it also means that the stack is no longer capable of producing a return status to indicate failure. To remedy this, the pam_deny.so module is added with required to the end of the stack to ensure that the entire process will still return a failure in case none of the previous modules return a success.


12. Result

At this point it should be possible to login to klac1 as user ccolumbus (password NewWorld), e.g. with ssh or at a console. Once there, run a few tests:

~$ id ccolumbus
uid=20001(ccolumbus) gid=20001(ccolumbus) groups=20001(ccolumbus)
~$ _

This account looks totally normal, including the GID number that is set to 20001 (instead of 65534 when AFS is used to store account meta-data).

~$ pwd
/afs/example.com/user/c/cc/ccolumbus
~$ _

The above command prints the name of current/working directory, showing that it is already set to the account's AFS mount point. This is despite the fact that a normal /home/ directory still exists, which is fine because that can still be used for Unix-only accounts. Otherwise, users with AFS accounts can login to any AFS client machine and always expect to be greeted by their own personal environment − wherever you go, there you are!


13. See also
14. 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.
  • Samar V, Schemers R. 1995. RFC 86.0 − Unified Login with Pluggable Authentication Modules (PAM). Open Software Foundation. Text at The Open Group.
  • 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.

15. 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).
  • 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: 2010-12-07, 22:38

©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.