Kerberos/LDAP/NFSv4 HOWTO

These instructions are specific to Redhat Enterprise Linux (RHEL), Version 4. A combination of RHEL AS (for servers) and RHEL WS (for workstations) were used. Interoperability with other clients is possible, but is not addressed here (but refer to the references below for links that may be helpfull).

The goal of this document is to describe how to setup a network so that the following are attained.

  • User authentication is done using a central Kerberos server.
  • User information (UID/GID/home directories) are stored in an LDAP directory.
  • Store NFS automount information in LDAP.
  • NFSv4 authentication using Kerberos is possible with support for legacy NFSv3 mounts.

This document will not explain why kerberos, ldap or NFSv4 are good things. If you aren’t convinced, then read up on the subject. If you are convinced, then read on.

Prerequisites

Time Synchronization

All machines that will participate in kerberos authentication must have a reliable, synchronized time source. Most large orgainization offer their own time sources. You can use the RHEL configuration tool system-config-time to set this up.

:howto:system-config-time.gif

If the different in time between systems varies by more than a small amount (usually five minutes), systems will not be able to authenticate.

Host Names

All hosts must have their hostname set to the fully qualified hostname as reported by DNS. Both forward and reverse mapping must work properly.

[root@phoenix ~]# hostname
phoenix.physik.unizh.ch
[root@phoenix ~]# dig phoenix.physik.unizh.ch +short
130.60.164.29
[root@phoenix ~]# dig -x 130.60.164.29 +short
phoenix.physik.unizh.ch.

The host may be referenced by a CNAME, but the official host name (as reported by hostname) must be an ‘A’ record. This is important; if you don’t have this setup properly then some things will work, while other things will fail mysteriously.

If the host name does not match the reverse DNS lookup, Kerberos authentication will fail.

Packages

Before starting, verify that the necessary RPM packages are installed. The packages required are different for a client or a server.

SPECIAL NOTE: Red Hat Enterprise Linux 4 installed on a 64-bit processor can sometimes install the 32 bit version of packages. When verifying that the packages are correctly installed, make sure that the 64 bit version is there if you are on a 64 bit architecture. I had endless grief getting ldap to work until I realized that the Red Hat installer had installed the 32 bit version of cyrus-sasl-gssapi on our 64 bit machine. All of the other packages were correct, or both were installed. To verify a package, use the following command.

[root@coma ~]# rpm -q --queryformat="%{n}-%{v}-%{r}.%{arch}\n" cyrus-sasl-gssapi
cyrus-sasl-gssapi-2.1.19-5.EL4.i386
[root@coma ~]# up2date --arch=x86_64 cyrus-sasl-gssapi
Fetching Obsoletes list for channel: rhel-x86_64-as-4...
Fetching rpm headers...

Installing...
  1:cyrus-sasl-gssapi ########################################### [100%]
[root@coma ~]# rpm -q --queryformat="%{n}-%{v}-%{r}.%{arch}\n" cyrus-sasl-gssapi
cyrus-sasl-gssapi-2.1.19-5.EL4.i386
cyrus-sasl-gssapi-2.1.19-5.EL4.x86_64

If you are on a 32 bit architecture, then this is something that you don’t need to worry about.

Client Packages

  • krb5-libs
  • krb5-workstation
  • pam_krb5
  • cyrus-sasl-gssapi
  • openldap-clients

Server Packages (KDC and LDAP)

The server will need all of the client package in addition to the following.

  • krb5-server
  • openldap-servers

What's in a Name?

At this point, you should have all of your machines registered in DNS under one (or more) domains. In our case, our machines are in the physik.unizh.ch domain. We also authenticate our supercomputers which are in the zbox.physik.unizh.ch domain.

You need to choose a kerberos realm. A kerberos realm is completely different from a DNS domain, but in most cases you will want to use the same name. By convention, kerberos realms are all upper case. Our kerberos realm is PHYSIK.UNIZH.CH. This realm serves both the physik.unizh.ch and the zbox.physik.unizh.ch DNS domains.

There is also a distinction between a unix username and a kerberos principal. You will be creating a kerberos principal for every unix username for which you want to use kerberos authentication. In addition, you will be creating additional kerberos principals for additional purposes (more on this later).

In this document, when I say domain, I mean an DNS domain. When I say realm, I mean a kerberos realm. When I say username, I mean a unix user and when I say principal, I mean a kerberos principal.

Kerberos

Kerberos Server (KDC)

The first step is to setup a kerberos server (or KDC).

File Modifications

There are a number of files that have to be manually edited on the server.

Edit /etc/krb5.conf

The stock version of this file will have EXAMPLE.COM or example.com everwhere you want to put your own realm or domain name. The two sections in question are libdefaults and domain_realm. The other sections do not need to be changed. In libdefaults, enter your own kerberos realm name. You may want to set the clock skew to a lower value (provided you are synchronizing time with ntp).

[libdefaults]
 default_realm = PHYSIK.UNIZH.CH
 dns_lookup_realm = false
 dns_lookup_kdc = false
 clockskew = 120

The realms section contains the settings for each realm. We have only one realm so it would look like the following. Note that you enter a kdc line for each Kerberos Domain Controller. You should have at least two.

[realms]
 PHYSIK.UNIZH.CH = {
  kdc = coma.physik.unizh.ch:88
  kdc = second.physik.unizh.ch:88
  admin_server = coma.physik.unizh.ch:749
  default_domain = physik.unizh.ch
 }

In domain_realm, enter the mapping between DNS domains and your kerberos realm. If you are serving multiple DNS domains, you need to put them all here.

[domain_realm]
 .zbox.physik.unizh.ch = PHYSIK.UNIZH.CH
 zbox.physik.unizh.ch = PHYSIK.UNIZH.CH
 .physik.unizh.ch = PHYSIK.UNIZH.CH
 physik.unizh.ch = PHYSIK.UNIZH.CH

Finally, you may want to tweak the application defaults, for example to change the renew lifetime.

[appdefaults]
 pam = {
   debug = false
   ticket_lifetime = 36000
   renew_lifetime = 36000
   forwardable = true
   krb4_convert = false
 }
 kinit = {
   ticket_lifetime = 36000
   renew_lifetime = 36000
   forwardable = true
 }

Edit /var/kerberos/krb5kdc/kdc.conf

In this file, only the realms section needs to be modified. According to this FAQ, it is important to change the key types as well. I can confirm that the setting below work perfectly in our environment. You may want to decide on appropriate values for the maximum life of each ticket, and for how long each ticket can be renewed. Reasonable values are 1 day and 1 week but your needs will vary. The values here are the absolute maximum that the KDC will issue. Each principal has its own maximum as well.

[realms]
 PHYSIK.UNIZH.CH = {
  master_key_type = des3-hmac-sha1
  supported_enctypes = des3-hmac-sha1:normal des-cbc-crc:normal
  max_life = 25h
  max_renewable_life = 4w
 }

Edit /var/kerberos/krb5kdc/kadm5.acl

This file determines who can modify the kerberos database. You need to change the realm.

*/admin@PHYSIK.UNIZH.CH *

A brief note on kerberos users (called principles) is in order at this point. All standard users will be of the form username@REALM. When one tries to run the administration tool, it takes the current username, appends ‘/admin’ and uses that as the principle. If there is no username/admin@REALM principle, then that user cannot modify the database.

Change /etc/gssapi_mech.conf

There is a problem with this file on 64-bit architectures. It specifies the “lib” library path instead of the “lib64” path. You can just remove the path altogether and it will work on either. This is more important on a kerberos client, but a server can be a client as well, so you may as well change it on all machines.

# library                               initialization function
# ================================      ==========================
# The MIT K5 gssapi library, use special function for initialization.
libgssapi_krb5.so                       mechglue_internal_krb5_init

Create the Kerberos database

Create the database with the following command.

  [root@coma ~] kdb5_util create -s

This will prompt you for a password. You will only have to enter this password when you initially configure a slave KDC, so choose something large and random and store it in a secure place. Really, you may only have to enter this once more, so make it secure.

Add the first Administrative User

I do administration as root, so the first user I add is root/admin. The default realm is appended automatically, so the command to use is as follows.

  [root@coma ~] kadmin.local -q "addprinc root/admin"

Enter a password when prompted. You will need this password every time you administer the database.

Starting the Services

At this point it is necessary to enable and start the kerberos services.

  [root@coma ~] chkconfig kadmin on
  [root@coma ~] service kadmin start 
  [root@coma ~] chkconfig krb5kdc on
  [root@coma ~] service krb5kdc start

To test if everything is working, run kadmin. By default, the current user appended with ‘/admin’ is used as the principle.

  [root@coma ~] kadmin
  Authenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH: 
  kadmin:  listprincs
  K/M@PHYSIK.UNIZH.CH
  kadmin/admin@PHYSIK.UNIZH.CH
  kadmin/changepw@PHYSIK.UNIZH.CH
  kadmin/history@PHYSIK.UNIZH.CH
  krbtgt/PHYSIK.UNIZH.CH@PHYSIK.UNIZH.CH
  root/admin@PHYSIK.UNIZH.CH

The additional principles have been created by the tool. They are required so leave them be.

Create a Host Principal for the KDC

Now you will want to create a host principal for the KDC. This is required for replication (see below). You also need to add this principal to the local key table.

  [root@coma ~]# kadmin
  Authenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH:
  kadmin: addprinc -randkey host/coma.physik.unizh.ch
  NOTICE: no policy specified for host/coma.physik.unizh.ch@PHYSIK.UNIZH.CH; assigning "default"
  Principal "host/coma.physik.unizh.ch@PHYSIK.UNIZH.CH" created.
  kadmin: ktadd host/coma.physik.unizh.ch

Setup the default Policy

You will want to create the default password policy at this point. All new accounts will have this policy enforced.

  [root@coma ~] kadmin
  Authenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH: 
  kadmin: add_policy -maxlife 180days -minlife 2days -minlength 8 -minclasses 3 -history 10 default

You can also add other policies and apply different policies to different principles. The different flags and their meaning are as follows.

Flag Description
-maxlife The is the maximum period before the password must be changed.
-minlife This is the minimum time after a password change before it can be changed again. Without a minimum time, users can change their password multiple times and overflow the history (see below) and end up back with the same password.
-minclasses This is the number of distinct character classes that must appear in the password. Character classes are uppercase letters, lowercase letters, number and symbols. Setting this to 2 for example would mean a password with at least one lowercase letter and a number would be valid.
-history This is the number of previous passwords to keep. A password may not duplicate a prior password.

Changing the Maximum Renewal Time

Each principal has its own maximum renewal life. On RHEL4, new principals are created with a maximum renewal time of zero. This means you can get a renewable ticket, but they can never be renewed. Each principal must be manually changed to the desired maximum renewal time. In addition, the special principal krbtgt/REALM@REALM must be changed to reflect the maximum renewal time that any principal will have.

  [root@coma ~]# kadmin
  Authenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH: 
  kadmin:  modprinc -maxrenewlife 2weeks krbtgt/PHYSIK.UNIZH.CH@PHYSIK.UNIZH.CH
  Principal "krbtgt/PHYSIK.UNIZH.CH@PHYSIK.UNIZH.CH" modified.

Adding Principals

  [root@coma ~] kadmin
  uthenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH: 
  kadmin: addprinc -maxrenewlife 7days doug

The various options allow you to tune your password policy.

Slave KDC (Backup KDC)

At this point, you will want to setup a backup or “slave” KDC.

Host Principal

First, add a host principal for each slave KDC. If you followed the instructions above for the primary KDC, then you will already have a host principal for the primary.

  [root@coma ~]# kadmin
  Authenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH:
  kadmin:  addprinc -randkey host/second.physik.unizh.ch
  NOTICE: no policy specified for host/second.physik.unizh.ch@PHYSIK.UNIZH.CH; assigning "default"
  Principal "host/second.physik.unizh.ch@PHYSIK.UNIZH.CH" created.

Copy Configuration Files

Copy the following files from the primary KDC to each of the slave KDCs.

  • /etc/krb5.conf
  • /var/kerberos/krb5kdc/kdc.conf
  • /var/kerberos/krb5kdc/kadm5.acl
  • /etc/gssapi_mech.conf

Create kpropd.acl

Create an ACL file with all of the KDCs listed (both primary and backups). This file is /var/kerberos/krb5kdc/kpropd.acl and should look something like this.

host/coma.physik.unizh.ch@PHYSIK.UNIZH.CH
host/second.physik.unizh.ch@PHYSIK.UNIZH.CH

Don’t put this file on the primary KDC or kadmin will not start.

Add Host Principal to Slave Key Table

On each slave KDC, add the host principal to the local key table.

  [root@second ~]# kadmin
  Authenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH:
  kadmin:  ktadd host/second.physik.unizh.ch

Start the Kerberos Propagation Daemon

On RHEL4 it is not necessary to create the database on the slave prior to starting the daemon. It was reported (thanks Louis) that on Fedora and perhaps Centos it is required. If the kprop daemon doesn’t start, you may need to create the database with the “kdb5_util create -s” command before starting it.

On each slave KDC, use the following command to enable the receipt of the kerberos database.

[root@second ~]# chkconfig kprop on
[root@second ~]# service kprop start
Starting Kerberos 5 Propagation Server:                    [  OK  ]

Propagate the Database

The next step is to propagate the database (manually) to each slave KDC. This is a two step process. First, dump the database to a file. Next, propogate the dumped file to each slave KDC.

  [root@coma ~]# kdb5_util dump /var/kerberos/krb5kdc/slave_datatrans
  [root@coma ~]# kprop -f /var/kerberos/krb5kdc/slave_datatrans second.physik.unizh.ch
  Database propagation to second.physik.unizh.ch: SUCCEEDED

Create a Stash File

On each KDC you need to create a stash file. You will need the (really long and random) master key that you entered when you initially created the kerberos database.

  [root@second ~]# kdb5_util stash
  kdb5_util: Cannot find/read stored master key while reading master key
  kdb5_util: Warning: proceeding without master key
  Enter KDC database master key:

Start the Kerberos 5 KDC on each Slave

Now that the database is there, and you have created the stash file, you are ready to start the KDC Daemon.

  [root@second ~]# chkconfig krb5kdc on
  [root@second ~]# service krb5kdc start
  Starting Kerberos 5 KDC:                                   [  OK  ]

Do not start the Administration Daemon (kadmin) on the slaves. The Administration Daemon is used to add/remove/modify principals and to change passwords. When the database is replicated to the slaves, any changes that were made on the slaves would be lost. This also means that if the primary KDC goes down, it is not possible to make changes, or for users to modify their password.

If the primary KDC will be down for an extended period, you can make any slave the primary, but you will have to replicate the database back to the old primary when it becomes available. This requires manual intervention.

Setup Periodic Replication

Replication from the Master KDC to the slaves is not automatic. You need to set up a cron job. Create a script similar to the following and place it into /etc/cron.hourly.

#!/bin/sh
KDCS="second.physik.unizh.ch"

/usr/kerberos/sbin/kdb5_util dump /var/kerberos/krb5kdc/slave_datatrans

for KDC in $KDCS ; do
    /usr/kerberos/sbin/kprop -f /var/kerberos/krb5kdc/slave_datatrans $KDC \
        | grep -v SUCCEEDED
done

You can change how often replication is performed to suit your needs. If you makes changes to the database, you can manually run the script to propagate them. If the primary KDC goes down, then any changes since the last propogate will not be reflected (hence if a user password has changed, the old password will be valid, not the new one).

Firewall Configuration

It is highly recommended that a firewall (for example iptables) be used to restrict access. For kerberos to work, the following ports must be opened.

  • Clients must be able to reach all KDCs on UDP port 88 (for authentication).
  • Clients must be able to reach the primary KDC on TCP port 749 (for password management).
  • The primary KDC must be able to reach the secondary KDCs on TCP port 754 (for replication).

LDAP

Please read the section below on crash recovery. If the LDAP server (slapd) is not shutdown properly (e.g., your machine crashes) then your LDAP database will be trashed. The LDAP server will start and answer requests but won’t produce any fruitfull results. Nobody will be able to log in!

Kerberos

Your LDAP server must be configured to use kerberos. If you are running your LDAP server on the same machine as your kerberos KDC, then everything is setup, otherwise see the client section below.

You will need to create a kerberos principal for each LDAP server. The special principal, ldap/hostname must be extracted to a key table to which the LDAP server (slapd) has access.

  [root@coma ~]# kadmin
  Authenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH:
  kadmin:  addprinc -randkey ldap/coma.physik.unizh.ch
  kadmin:  ktadd -k /etc/openldap/ldap.keytab ldap/coma.physik.unizh.ch
  kadmin:  exit
  [root@coma ~]# chgrp ldap /etc/openldap/ldap.keytab
  [root@coma ~]# chmod 640 /etc/openldap/ldap.keytab

You need to repeat this process on each LDAP server (of which there should be at least two).

You have to tell slapd to use this key table by editing /etc/sysconfig/ldap. It should look like this.

export KRB5_KTNAME=/etc/openldap/ldap.keytab 

SSL Certificate

The LDAP server will require an SSL certificate. Of course, you can purchase one, but this isn’t necessary. Unlike web or mail servers, the certificate authority can be easily distributed to the clients during configuration. The openssl package provides the necessary scripts.

See Certificates HOWTO for details on creating a certificate.

If you plan to use an alias for your ldap server, then the certificate must contain all of the aliases. For example, let’s suppose you will have to ldap servers called host1.domain and host2.domain. You plan to have an alias called ldap.domain that will round robin. Further, a different domain will also reference the servers as ldap.otherdomain. You need to add the following line to openssl.conf before generating the certificates (in the usr_cert section).

subjectAltName=DNS:ldap.domain,DNS:ldap.otherdomain

Name each server normally (host1.domain and host2.domain).

slapd.conf

Now edit /etc/openldap/slapd.conf and make the following changes.

TLSCACertificateFile /etc/openldap/cacerts/cacert.pem
TLSCertificateFile /etc/openldap/slapd.pem
TLSCertificateKeyFile /etc/openldap/slapd.key

There are some additional changes that need to be made to this file, so we might as well do them now.

Add an idle timeout.

idletimeout 3600

Failure to add this idle timeout will result in LDAP failing after a period of time. The number of TCP connections is limited internally. If connections are not released, the LDAP daemon (slapd) will be unable to open files. This will cause slapd to return an error to all queries. At this point nobody will be able to logon or do much of anything. If this value is too high (or disabled), then slapd will run out of file handles. If this value is set too low, then your system log will be filled with messages about reconnecting to the LDAP server. On our system, the value 3600 (1 hour) works well.

You need to change the suffix and rootdn to match your domain. Here is an example.

suffix          "dc=physik,dc=unizh,dc=ch"
rootdn          "cn=Manager,dc=physik,dc=unizh,dc=ch"

You also need to add a a temporary manager account for the initial load. The best thing to do here is to add an encrypted password. First run slappasswd to encrypt a password.

  [root@coma ~]# slappasswd 
  New password: 
  Re-enter new password: 
  {SSHA}ISM1CdMvg6jOMNjASCKZvOWxXy6F8jY4

Now change the rootpw section.

rootpw                  {SSHA}ISM1CdMvg6jOMNjASCKZvOWxXy6F8jY4

Change the access control section as follows.

# This is a bit of a hack to restrict the SASL mechanisms that the
# server advertises to just GSSAPI.  Otherwise it also advertises
# DIGEST-MD5, which the clients prefer.  Then you have to add "-Y
# GSSAPI" to all of your ldapsearch/ldapmodify/etc. command lines, which
# is annoying.  The default for this is noanonymous,noplain so the
# addition of noactive is what makes DIGEST-MD5 and the others go away.
sasl-secprops noanonymous,noplain,noactive

# Map SASL authentication DNs to LDAP DNs
#   This leaves "username/admin" principals untouched
sasl-regexp uid=([^/]*),cn=GSSAPI,cn=auth uid=$1,ou=people,dc=physik,dc=unizh,dc=ch
# This should be a   ^  plus, not a star, but slapd won't accept it

# Users can change their shell, anyone else can see it
access to attr=loginShell
        by dn.regex="uid=.*/admin,cn=GSSAPI,cn=auth" write
        by self write
        by * read
# Only the user can see their employeeNumber
access to attr=employeeNumber
        by dn.regex="uid=.*/admin,cn=GSSAPI,cn=auth" write
        by self read
        by * none
# Default read access for everything else
access to *
        by dn.regex="uid=.*/admin,cn=GSSAPI,cn=auth" write
        by * read

ldap.conf

This file needs to be propagated to each host, including the ldap servers. Only the following three lines need to be present.

BASE    dc=physik,dc=unizh,dc=ch
URI     ldaps://coma.physik.unizh.ch ldaps://second.physik.unizh.ch
TLS_CACERT /etc/openldap/cacerts/cacert.pem

Crash Recovery

If your LDAP server is not shutdown gracefully, then the database will become corrupt. There may be a solution to this problem, but I have yet to find it.

For this reason, it is a good idea to use a reliable machine for your LDAP servers, and to put said machines on a UPS.

Backup

Further, you must make regular exports of the LDAP database so that you can easily reimport them if there is a problem. The following script (or something like it) can be added to /etc/cron.hourly or /etc/cron.daily/ as you see fit. It uses slapcat to export the database on a regular schedule.

#!/bin/bash
BACKUPDIR=/root/ldap.backup
KEEPDAYS=30

# Make sure that the directory exists
mkdir -p $BACKUPDIR

# Create a new backup (and compress it).  Choose one of the following FILENAME
# patterns (or create your own).  The first has the hour and minute while the
# second has only the date.  You can run the second hourly to keep only one
# copy per day, but have it saved hourly.
#FILENAME=$BACKUPDIR/ldap.backup.$(date +%Y%m%d%H%M)
FILENAME=$BACKUPDIR/ldap.backup.$(date +%Y%m%d)
/usr/sbin/slapcat | gzip --best >${FILENAME}.new.gz
mv -f ${FILENAME}.new.gz ${FILENAME}.gz

# Delete old copies
OLD=$(find $BACKUPDIR/ -ctime +$KEEPDAYS -and -name 'ldap.backup.*')
[ -n "$OLD" ] && rm -f $OLD

Restore

To restore your database from the backup, you need to perform the following steps.

  • Stop the LDAP server
service ldap stop
  • Remove the old database (you may want to make a copy “just in case”)
rm /var/lib/ldap/*
  • Import the latest backup (unzip it first if required). Be patient as this takes a little while.
cd /root/ldap.backup/
gunzip ldap.backup.20060101.gz
slapadd -l ldap.backup.20060101
  • Change the ownership of the files.
chown ldap.ldap /var/lib/ldap/*
  • Restart the server
service ldap start

Client Setup

Copy Files

Copy the following files from the KDC or LDAP server.

  • /etc/krb5.conf
  • /etc/ldap.conf
  • /etc/openldap/ldap.conf
  • /etc/openldap/cacerts/cacert.pem

Create Kerberos Principals

Run kadmin on the server and create the following principals. Replace phoenix.physik.unizh.ch with the fully qualified name of the client machine. If you don’t plan to use NFS, then don’t add the second principal. You can always add it now, even if you aren’t planning on using NFSv4 at the moment; it won’t hurt anything.

  [root@coma misc]# kadmin
  Authenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH: 
  kadmin: addprinc -randkey host/phoenix.physik.unizh.ch
  kadmin: addprinc -randkey nfs/phoenix.physik.unizh.ch

Now run kadmin on the client. Add the above two principals to the keytab file as follows. Note the special way in which the NFS principal is added. This is important or again things will fail in mysterious ways.

  [root@phoenix ~]# kadmin
  Authenticating as principal root/admin@PHYSIK.UNIZH.CH with password.
  Password for root/admin@PHYSIK.UNIZH.CH: 
  kadmin: ktadd host/phoenix.physik.unizh.ch
  kadmin: ktadd -e des-cbc-crc:normal nfs/phoenix.physik.unizh.ch

Enable Authentication

Run the configuration tool by typing authconfig at the shell prompt. You will need to check ‘Use LDAP’ under ‘User Information’ and ‘Use Kerberos’ under ‘Authentication’.

:howto:authconfig.png

NFSv4

NFSv4 using Kerberos authentication in RHEL4 seems to be broken with the latest patch level. When I find a solution it will be posted here. LDAP and Kerberos for authentication of users works fine.

Create the necessary entries in /etc/exports. First, create an NFSv4 mount point. I would suggest /export. Next bind the real path to the NFSv4 mount point. In this example, we want to export the /data directory. We create /export/data for NFSv4 and mount /data there.

  mkdir -m 1777 /export
  mkdir /export/data
  mount -n --bind /data /export/data

You will need to add the mount command to /etc/rc.d/rc.local so that it is remounted after each boot.

# NFSv4 Mounts
/export      gss/krb5(sync,rw,fsid=0,insecure,no_subtree_check,anonuid=65534,anongid=65534)
/export/data gss/krb5(sync,rw,nohide,insecure,no_subtree_check,anonuid=65534,anongid=65534)

# Legacy mounts
/data        coma(sync,rw,nohide,insecure,no_subtree_check,anonuid=65534,anongid=65534,no_root_squash)

Modify /etc/idmapd.conf

You must change the domain to your current domain. Also, The user mapping for nobody should be updated.

[General]

Verbosity = 0
Pipefs-Directory = /var/lib/nfs/rpc_pipefs
Domain = physik.unizh.ch

[Mapping]

Nobody-User = nfsnobody
Nobody-Group = nfsnobody

[Translation]
Method = nsswitch

Modify /etc/sysconfig/nfs

To enable secure NFS, you must add the following line to /etc/sysconfig/nfs

SECURE_NFS=yes

If you are still using NFSv3 and a firewall, you may want to add the following definitions as well. Choose ports that are appropriate to your environment, although the listed values work well for us.

STATD_PORT=4000
LOCKD_TCPPORT=4001
LOCKD_UDPPORT=4001
MOUNTD_PORT=4002
RQUOTAD_PORT=4003

Finally, if you expect many connections to your NFS server, you may need to increase the number of NFS Daemon. This is done by adding a line similar to the following. Again, the number of NFS Daemons will depend on your environment. The default (which may change) is 8.

RPCNFSDCOUNT=16

Tips

Make Important Servers a Slave KDC

If you have important servers and want to increase their reliability, you can make them slave KDC or LDAP servers. The changes will be propagated to those machines and they can retrieve the information locally. This way, if your primary authentication servers go down, the other servers can continue to function.

Firewall

Here is a simple firewall example for a KDC.

-N trusted
-N ssh-INPUT
-N krb-INPUT
-A trusted -i lo -j ACCEPT
-A ssh-INPUT -s 130.60.164.0/255.255.255.0 -p tcp -m tcp --dport 22 -j ACCEPT
-A krb-INPUT -p udp -m udp --dport 88 -j ACCEPT
-A krb-INPUT -p tcp -m tcp --dport 749 -j ACCEPT
-A krb-INPUT -s 130.60.164.50 -p tcp -m tcp --dport 754 -j ACCEPT
-A krb-INPUT -s 130.60.164.133 -p tcp -m tcp --dport 754 -j ACCEPT
-A krb-INPUT -s 130.60.164.134 -p tcp -m tcp --dport 754 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -j trusted
-A INPUT -p tcp -m tcp --dport 22 -j ssh-INPUT
-A INPUT -j krb-INPUT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited

Troubleshooting

This HOWTO has an excellent troubleshooting section for kerberos and LDAP. Additional things to be on the lookout for are as follows.

Kerberos

No matter what I do, the renewal time always appears as zero.

You have to change the maximum renewal time in three places. First, make sure that /var/kerberos/krb5kdc/kdc.conf is correct. Next make sure that the special principal krbtgt/REALM@REALM is correct. Finally, make sure that the maximum value is set for your principal.

I receive the following error when creating a stash file on a slave KDC. stash: Decrypt integrity check failed while verifying master key

You have typed the master key incorrectly.

LDAP

Trying to use SASL authentication with LDAP (ldapsearch without ‘-x’) gives the following error. ldap_sasl_interactive_bind_s: No such attribute

This can occur when the cyrus-sasl-gssapi RPM is not installed. If you are running on a 64-bit architecture, make sure that the 64-bit version of the package is installed. In my case, only the 32-bit version was installed.

NFSv4

Attempting to mount using nfs4 hangs and the following error is in /var/log/message. kernel: decode_getfattr: xdr error 10008!

This one was a real hair-puller. Restart rpcidmapd on the NFS server. I’m sure that there is a good explanation for why this happens or how to prevent it, but I don’t have one.

Attempting to mount takes several seconds, but succeeds. The following error appears in /var/log/message. kernel: RPC: AUTH_GSS upcall timed out. kernel: Please check user daemon is running!

Again, this one is driving me crazy. NFS is correctly configured, but the problem disappeared when I added the server to /etc/hosts. I was also able to get it to work by running rpc.gssd interactively with logging enabled. If it was run interactively without at least one ‘-v’ it would revert to the old behaviour.

The rpcgssd service (rpc.gssd) fails won’t keep running.

If you are running on a 64-bit architecture, then check that the library is correct in /etc/gssapi_mech.conf. The default in RHEL is /usr/lib, but of course it needs to be /usr/lib64. You can omit the directory entirely and it will find the library as follows.

# library initialization function
# ================================ ==========================
# The MIT K5 gssapi library, use special function for initialization.
libgssapi_krb5.so mechglue_internal_krb5_init

References

A number of documents were referenced in the construction of this HOWTO. No single document was complete.

The documentation for Red Hat Enterprise Linux provides a good starting point.

http://www.redhat.com/docs/manuals/enterprise/

The following document was perhaps the most useful. It provided virtually all of the information required to setup Kerberos and LDAP for user authentication. This is the guide that made it all possible.

http://www.ofb.net/~jheiss/krbldap/howto.html

http://cryptnet.net/fdp/admin/kerby-infra/en/kerby-infra.html

http://linsec.ca/usermgmt/kerberos5.php

http://web.mit.edu/kerberos/www/krb5-1.2/krb5-1.2.5/doc/install.html

The following has general information about NFSv4 support in the linux kernel.

http://www.citi.umich.edu/projects/nfsv4/linux/

http://www.vanemery.com/Linux/NFSv4/NFSv4-no-rpcsec.html

This is the documentation for openldap.

http://www.openldap.org/doc/admin23/

License

Creative Commons License
Kerberos/LDAP/NFSv4 HOWTO by Doug Potter is licensed under a Creative Commons Attribution 3.0 Unported License.

 
howto/kerberos.txt · Last modified: 2008/08/19 16:43 by dpotter