Ldap with Kerberos


Ldap with Kerberos


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

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 example.com domain. We also authenticate our supercomputers which are in thezbox.example.com 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 isEXAMPLE.COM. This realm serves both example.com and the zbox.example.com 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 = EXAMPLE.COM
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]
EXAMPLE.COM = {
kdc = coma.example.com:88
kdc = second.example.com:88
admin_server = coma.example.com:749
default_domain = example.com
}
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.example.com = EXAMPLE.COM
zbox.EXAMPLE.COM = EXAMPLE.COM
.example.com = EXAMPLE.COM
example.com = example.com
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. 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]
EXAMPLE.COM = {
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@EXAMPLE.COM *
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@TESTKB with password.
Password for root/admin@TESTKB:
kadmin: listprincs
K/M@TESTKB
kadmin/admin@TESTKB
kadmin/changepw@TESTKB
kadmin/history@TESTKB
krbtgt/TESTKB@TESTKB
root/admin@TESTKB
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@EXAMPLE.COM with password.
Password for root/admin@EXAMPLE.COM:
kadmin: addprinc -randkey host/coma.EXAMPLE.COM
NOTICE: no policy specified for host/coma.example.com@EXAMPLE.COM; assigning “default”
Principal “host/coma.example.com@EXAMPLE.COM” created.
kadmin: ktadd host/coma.example.com
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@ EXAMPLE.COM with password.
Password for root/admin@ EXAMPLE.COM:
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@ EXAMPLE.COM with password.
Password for root/admin@ EXAMPLE.COM:
kadmin: modprinc -maxrenewlife 2weeks krbtgt/ EXAMPLE.COM @ EXAMPLE.COM
Principal “krbtgt/ EXAMPLE.COM @ EXAMPLE.COM ” modified.
Adding Principals

[root@coma ~] kadmin
uthenticating as principal root/admin@ EXAMPLE.COM with password.
Password for root/admin@ EXAMPLE.COM:
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@ EXAMPLE.COM with password.
Password for root/admin@ EXAMPLE.COM:
kadmin: addprinc -randkey host/second.example.com
NOTICE: no policy specified for host/second.example.comEXAMPLE.COM; assigning “default”
Principal “host/second.example.comEXAMPLE.COM ” 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.acland should look something like this.
host/coma.example.comEXAMPLE.COM
host/ second.example.comEXAMPLE.COM
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@ EXAMPLE.COM with password.
Password for root/admin@ EXAMPLE.COM:
kadmin: ktadd host/ second.example.com
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.testkb
Database propagation to second.testkb: 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.example.com “

/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@EXAMPLE.COM with password.
Password for root/admin@ EXAMPLE.COM:
kadmin: addprinc -randkey ldap/coma.example.com
kadmin: ktadd -k /etc/openldap/ldap.keytab ldap/coma.example.com
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.
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=example,dc=com”
rootdn “cn=Manager,dc=example,dc=com”
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=example,dc=com
URI ldaps://coma.example.com ldaps://second.example.com
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 secure.testkb 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@ EXAMPLE.COM with password.
Password for root/admin@ EXAMPLE.COM:
kadmin: addprinc -randkey host/secure.example.com
kadmin: addprinc -randkey nfs/secure.example.com
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@secure~]# kadmin
Authenticating as principal root/admin@ EXAMPLE.COM with password.
Password for root/admin@ EXAMPLE.COM:
kadmin: ktadd host/secure.example.com
kadmin: ktadd -e des-cbc-crc:normal nfs/secure.testkb
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 = testkb

[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

================================================================

Bu cevap yeterince yardımcı oldu mu?