Author

LDAPv3

Last updated

Turbo Fredriksson


Saturday, January 29, 2005



Over the last year (around May, 2001) I have tried to rewrite this HOWTO into a book, and get it published. So far my attempts have not been that successful. No one want's to publish it - my language seems to be 'lacking'. The major concerns (it seems) is that it's not "professional" enough (from what I have understand, a "professional" book should bee in third person - I written mine in first person "I did", "when I got this problem" etc). Maybe so, but this is the way I want to read about something that's difficult.

Is there any need for another book about this? Have a look at Implementing LDAPv3 for the parts I have decided to show in public. It contains the the Contents at A glance, Table of contents, and chapter one and three. It is color encoded, to show what's done and what's not... I'd appreciate comments. This example is a little old now, I can't be bothered to update it (it is after all an EXAMPLE :). However, I also managed to create a PDF of the first seventeen (17) pages, which includes the title page, Contents at a glance and Table of contents as it would look like if it was printed. This I'll try to update every now and then. Watch the bottom on the title page for date of PDF creation. It's updated automatically.

Quite a number of people (4000 unique web accesses in the first three months it was up) have had help from this book. There's a number of companies that got helped with this HOWTO. A lot of them software companies. How about thanking me (if it actually helped and saved time/money that is) by sending me something you/your company makes? One successful company makes a Linux desktop distribution. I would have liked a copy of that, it would have been nice :). No requirenments though!

I've decided to sell the book as is.
It's not completley finished (in my eyes), but it's finished enough for people to actually have use for it... I have written a chapter about OpenLDAP version 2.2 and all what that means concerning Berkeley DB, Cyrus SASL and it's hookup to the Kerberos services.

I'm selling it for $15 US as a PDF. In the 'demo', there's a PayPal button you can use for purchasing the book. Please also send me a mail about it (just incase :). Please do not use this link for general LDAPv3 questions!
For this money, you'll get 'free updates' to it everytime I add/rewrite something exeptional (i.e. when big updates happen).

I'm sorry I can't accept other payments than PayPal. The 'simple' reason for this is that my PayPal account is solely intended for my computer addictions. I just _love_ vintage machines that I buy via eBay etc. I'm not allowed to do that with the 'household money' :)

PLEASE don't try to haggle over the price! $15US isn't that much for a book about a highly specialised subject as LDAP and Kerberos. If you don't know whether this book will help you, I recomend the book published by O'Reilly (LDAP System Administration). It's $39.95US so it's entirely up to you. I write this note because I just got fed up with people trying to haggle and think that they can get my three years of work for free! Sorry if this note puts people of and is insulting, but I found the haggle VERY insulting my self...

SORRY.
A number of people have after payment mailed me again (a little more irritated/angry - no wonder, I would to!) and asked me 'where the f***k is my book'. Well, if I receive the money (and I'll get a receipt from PayPal that is hard to ignore) I'll send the book to the owner of the PayPal account. In some cases the person have requested that I send it to another address instead - no problem.
BUT, and this is what I think is the problem: The mail isn't reaching it's destination - the attachement (book) is 1.6Mb! Then it's no wonder that the person get's angry - not all mailservers allow that big attachements. Please verify with your ISP/Mail supplier that that size (plus a little to be sure :) is accepted...
Oh, and give me at least 2-3 days before starting to wonder where it is. I try to limit (especially on the weekends :) my time in front of the computers. It's just not as fun any more.

Indexed PDF.
Since I use OpenOffice.org to write the book I've managed to get extendedPDF to export PDF's with enbedded links and bookmarks. If anyone of those that bought the book wants that version, please send me a mail requesting it (no charge). All new payments will receive that version instead...

August 23, 2007:
Sent my 150'th copy. Thanx to all that thought/think it was worthwhile.
January 6, 2008:.
Sent my 160'th copy.

Preface

These are my notes about how I got OpenLDAP (v2.0.7), OpenSSL (v0.9.5a), SASL (v1.5.24) and MIT KerberosV (v1.2.2) to work together. This combination (according to some RFC I can't remember the number of) is what's called LDAPv3.

I have since I initially wrote this HOWTO, upgraded some packages. The information about this can be found in the Updates section. At the time of this writing (Sunday, August 19, 2001) I have not successfully compiled and installed OpenLDAP v2.0.11! I'm still working heavily on this, it is at the top of my todo list, since I really (!!) need to upgrade because of a resent security alert.

You might want to read the section LDAPv3, why bother to see the reasoning for this quite complicated issue. It deals with all the discussed systems, such as SSL/TLS, SASL, LDAP and Kerberos, and why we should run such a complicated system in the first place.

Required knowledge

Reading and following this documentation will require a knowledge of LDAP in general, knowing how to create and install software 'from scratch' (i.e. building from source/tar balls) and also how to configure OpenLDAP and also how to administer it... This issue (LDAPv3) is not for the beginner, and I will usually not answer any questions in the format of 'I get this when i try to configure/make/install this-or-that-software'! In short, you will be required to 'read between the lines' of this document, and draw you own (correct! :) conclutions. That being said, it's not as difficult as it might seem. If you belong to the group of people that I here call 'beginner', I recommend installing the software while reading the OpenLDAP web page on OpenLDAP administration.

Note about building software

I'm running Debian GNU/Linux on all my machines, both on the Intel platform and the Sun SPARC, and prefer to use the Debian package system as much as I can. Since I'm also a Debian developer, I have a fairly good know-how about making a Debian package. In my pursuit of getting this to work, I had to modify some of the default packages since they lacked some features that is necessary. I will try to guide you through the process of rebuilding you package, if you to are running Debian GNU/Linux. If you are not, I will at least tell you which parameters to configure etc. the Debian package are using, giving you at least SOME hint on getting all this software compiled and installed :). Also, the progress and fast moving target that the Internet and the OpenSource movement are, the versions I have described here are most likely already out of date. Two weeks after I started with this HOWTO, Cyrus-SASL had released version 1.5.26, that fixed the problem described in the section Bugs in Cyrus SASL, v1.5.24. But I'm deploying this any day now on a live server, so I won't be able to test if it indeed fixes the problem.

Note about text notation:

Wherever you see the <> (in bold) part, it means that that's where you input your own information. So for example, when you see

<YOUR KERBEROS REALM>

It means that you should put your realm in there, like this:

BAYOUR.COM

Note, that you should NOT include the characters < and >!.

Also, I assume in this document that the configuration for OpenLDAP2 is installed into /etc./ldap. If you haven't installed it there, please remember to exchange that path to your path.

Disclamer

Please don't send any 'please help me' mails directly to me. Direct it to the appropriate mailing lists for help instead, you stand a much better chance of getting a reply if you do. I just don't have the time (or knowledge) to help anyone/everyone in private.

Any mails sent to me about any of this will be replied to on a public list.

Table of Contents – Core software

BerkeleyDB

BerkeleyDB from SleepyCAT is, from what I have read/tried a better database back-end than gdbm, ndbm and db. It is used by OpenLDAP to store the database on disk. Your call, you don't have to use it, but I like it and have been using it all the time.

Building and installing Berkeley DB

OpenSSL

This is the software that will give us TLS and SSL enabled LDAP (secure and encrypted communication). It have nothing to do with AUTHENTICATING a user, it just gives us a way to encrypt traffic to/from the LDAP server.

Build OpenSSL

Creating SSL certificate

MIT Kerberos V

This is what we will use to store password in. It will, as a bonus, also give us a 'single-sign-on' system (that is, you enter your passphrase/password once, and the 'ticket' that is returned, will be used for login authentication).

Building MIT Kerberos V

Bugs in MIT Kerberos V, v1.2.1

Bugs in MIT Kerberos V, v1.2.2

Installing MIT Kerberos V

Configure Kerberos

Preparing the DNS for KerberosV

Kerberos config file

Create KerberosV realm

Setting up KerberosV access rights

Testing MIT Kerberos V

Cyrus SASL

This is the layer between OpenLDAP and Kerberos. It gives you a secure way of AUTHENTICATING access to the LDAP server. It will not encrypt the actual traffic (even though the authentication session is encrypted).

Building Cyrus SASL

Bugs in Cyrus SASL, v1.5.24

Build the Cyrus SASL packages

Installing Cyrus SASL

Testing Cyrus SASL

OpenLDAP

Well, we all know what this is, don't we? It's a free LDAP server. A very (VERY) good one to, in my opinion (even though I don't have much experience in other LDAP server :).

Building OpenLDAP v2

Bugs in OpenLDAP, v2.0.7

Installing OpenLDAP v2

Configuring OpenLDAP v2

Configure OpenLDAP to use the new SSL certificate

Changes to the OpenLDAP config file

Changes to the OpenLDAP startup script

The OpenLDAP config file

The OpenLDAP access file

Creating a LDAP service key

Populate the database to allow simple bind as user

Modify the LDAP database to allow simple bind as user.

Notes about 'userPassword: {KERBEROS}'

Testing OpenLDAP v2

Testing OpenLDAP, simple/anonymous bind

Testing OpenLDAP, simple/anonymous bind, with SSL/TLS

Testing OpenLDAP, using your Kerberos ticket

Testing OpenLDAP, using your Kerberos ticket, with SSL/TLS

Testing OpenLDAP, simple user bind, with SSL/TLS

Setting up secure replication

Replication configuration, slave server

Replication configuration, master server

Creating a replication principal

Automatically getting a ticket before starting slurpd

Keeping replication ticket updated

Give the replicator access to the database

Table of Contents – Miscellaneous software

Some software to ease administration and migration to LDAP/Kerberos are these softwares. I'm not going to go in to how to get this configured and installed. That's an exercise for the reader :). They have no real relevance for getting LDAPv3 to work, but I thought I'd plug for them anyway, because I have found them invaluable in using and administrating LDAP in general.

LibNSS-LDAP/LibPAM-LDAP

The LDAP name service switch (NSS) module is an Open Source project to integrate LDAP as a native name service under Linux, Solaris, and other operating systems. The LDAP pluggable authentication module (PAM) is an Open Source project to integrate LDAP authentication into operating systems supporting the PAM API, such as Linux, Solaris, and HP-UX.

Building and installation

Downloading source

Building packages

Install the newly made packages

Concurrent Version System

Not related with OpenLDAP really, but I'm going to show you a little how to get CVS linked and compiled with GSSAPI so that we can use our Kerberos key for authentication to the cvs server.

Building CVS

Configure options

With Krb4 option

Creating a CVS service key

Cyrus IMAP/POP3

Quite naturally we would like the IMAP and POP3 server to authenticate directly with SASL to the Kerberos database as well.

Building Cyrus IMAP and POP3 server

Configure Cyrus IMAP and POP3 server

Creating a IMAP/POP3 service key

OpenAFS

From the project page:

AFS is a distributed filesystem product, pioneered at Carnegie Mellon University and supported and developed as a product by Transarc Corporation (now IBM Pittsburgh Labs). It offers a client-server architecture for file sharing, providing location independence, scalability and transparent migration capabilities for data.

Kind'a like NFS with Kerberos authentication. Although AFS is a (network) file system and have don't have anything to do with LDAPv3, it is 'essential' for a distributed (and load balanced) server cluster.

OpenAFS

Building OpenAFS

Build OpenAFS kernel module

Installing OpenAFS

OpenAFS KerberosV support software

Building OpenAFS KerberosV support software

Installing OpenAFS KerberosV support software

Configure OpenAFS KerberosV support software

OpenAFS PAM module

Building and Installing the OpenAFS PAM module

Configure OpenAFS PAM module

Configure OpenAFS

Creating a AFS service key

Putting the AFS service key into the AFS KeyFile

Mount the AFS volume

Create the new cell

Setup the cell configuration files

Getting a Kerberos ticket and a AFS token

Setting up root volumes

Testing the OpenAFS softwares

Testing OpenAFS KerberosV support software

Testing OpenAFS PAM module

Samba

The idea here is to make a Windows 2000 server out of our Linux/UNIX box. In theory (at least from what I have understood from mails on the openldap-software list) this should be possible if using Krb5, SASL, LDAP and Samba. I'm currently investigating this issue.

Check back every now and then to see how far I have got with this.

Building Samba/Samba-TNG

Compile options

Make string

Directory Administrator

From the project page:

Designed with the only focus of being a tool to easily manage UNIX users and groups in an LDAP directory, corporate information, access controls, and LDAP mail routing.

I'm currently writing a patch for this, to allow it to add the principal to the KDC as well as adding the user stuff in the LDAP server. Also in progress are SASL and SSL/TLS binds to the LDAP server.

PAM/Kerberos migration module

I haven't gotten this to work yet, but I'm working on it. From the source code README:

pam_krb5_migrate is a stackable authentication module (for PAM) that takes a user name and password from an earlier module (such as pam_ldap or pam_unix) in the stack, and attempts to transparently add them to a Kerberos realm using the Kerberos 5 kadmin service. The module can be used to ease the administrative burdens of migrating a large installed user base from pre-existing authentication methods to a Kerberos based setup.

Looks nice to me, if I just could get it to work!

Have a look at Migrating existing users for more information about migrating existing users.

QMAIL with LDAP patches

It is possible to have QMAIL look in a LDAP database for it's email addresses, and to have QMAIL's pop/imap server authenticate the users from a LDAP database.

Sendmail and LDAP

I'm not using Sendmail, in fact, I dislike sendmail quite heavily. In my opinion it's the most insecure piece of software you can install on a UNIX (like) platform. But, granted, it's the only (mail) server that can cope with hundred of thousands (and above) of mails. I'll see if I can dig up some information about this, and add this to this HOWTO/FAQ.

In the mean time, have a look at the URL: http://www.stanford.edu/~bbense/Inst.html.

Miscellaneous information

Here you can find some reference material, and copies of my configurations discussed in this document

Updates

Most things in the Open Source movement change quite fast, and software naturally gets updated. Instead of adding a 'updates' section under each software product, I have gathered them here instead, sorted by the latest version at the time of writing.

BerkeleyDB

v3.3.11







OpenSSL

v0.9.6a

v0.9.6b






OpenLDAP

v2.0.10

v2.0.11

v2.0.14

v2.0.18

v2.0.21

v2.0.22

v2.0.23

CyrusSASL

v1.5.27







MIT KerberosV

v1.2.4







My configuration files

These are copies on all my configuration files. They are documented here in the document, but just a preventive measure, I thought that I'd include the actual files as well.

Master LDAP server

Slave LDAP server

PAM/LDAP files

Misc files

Reference material

This are some misc information about where to find more information about RFC's and Internet drafts etc.

Patches

LDAP

LDAPv2

LDAPv3

Authentication

SASL

Kerberos

Other

Problems that can occur

After getting all this software configured, compiled and installed, it will need to work independent of the other. That is, each piece needs to work before we can start gluing them together. There's always something that can go wrong. Here's examples and solutions for some of (the most common?) ones.

Problems when the KVNO don't match up.

No such attribute error

No such object error

Local error

Problems with ACL's

SLAPADD problems/messages

Attribute type undefined

Attribute not allowed

Missing required attribute

Shortcuts

For the lazy ones, why not take a look at this section.

No guaranties though!

APT configuration

These are the packages that are available for installations

KerberosV server

KerberosV client

KerberosV services

PAM/NSS

Miscellaneous

OpenSSL

Cyrus SASL

OpenLDAP2

OpenAFS

PostgreSQL

Migrating existing users

Some notes about migrating an existing user database, be it the old fashioned /etc/passwd approach, NIS/NIS++ etc.

Thanx to

I would like to thank the following people, in no special order(!), for giving me input on this document. I apologize if I forgot someone (I started this thank you part quite late in the process :).

Johann Botha

For noting that we have to start the SLAPD server on port 636 aswell

Allan Streib

For the patch to Cyrus SASL, v1.5.27

Jorge Santos

For pointing out that Berkeley DB 3.2.9 is in Debian GNU/Linux under the name libdb3/libdb3-dev. Also found a missing '-exec' in a find command (in the Building Packages subsection of the libpam-ldap and libnss-ldap section).

John Rodger

Which had a one month newer version than the file I had in my backup when I lost the whole page because of user error :)

Keith R Lally

For finding the latest version of the lost document.

Jasper Möller

For some question and remarks about the DNS setup, migration of existing users, SSL certificates etc.

Kim Holburn

Replication configuration and setup

Thanx for all the support and input

Building required software

OpenSSL

Installing the Debian GNU/Linux package

This package I just installed right of the Debian GNU/Linux non-US FTP site, using apt-get install libssl09 libssl09-dev openssl. The development package are needed later when building OpenLDAP v2.

Building OpenSSL from scratch

For those of you that don't use Debian, this are the configure command line:

./Configure shared --prefix=/usr --openssldir=/usr/lib/ssl

Then build the package by issuing this command:

make -f Makefile.ssl all

Install newly built OpenSSL software

To install OpenSSL after executing make, issue this command:

make -f Makefile.ssl  install.

That's about it about OpenSSL I think, but as I said, I just installed the Debian packages, and where done with it :)

Creating SSL certificate

To create the certificate that OpenLDAP will use, we issue the command openssl like this:

openssl req -new -x509 -nodes -out server.pem -keyout server.pem -days 365

This is what the command will output when I do it. The first line might be different in your installation, and some of the wordings might have changed if you are using a different version than me. The important information you should input is on the last seven lines (starting with Country Name and ending with Email Address. Parts in bold+underline is my responses:

Using configuration from /usr/lib/ssl/openssl.cnf
Generating a 1024 bit RSA private key
.....++++++
.................................................++++++
writing new private key to 'server.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:SE
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:Gothenburg
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:egeria.bayour.com
Email Address []:turbo@bayour.com

It is very important that you don't give localhost for the Common Name. It should be your hosts FQDN (Fully Qualified Domain Name). That is, what's your IP address, and what name does the DNS tell you belong to this IP address?

NOTE: I can not stress this enough! 99% of all the "SSL/TLS don't work" mails on the openldap-software list is due to the fact that someone have not used a correct Common Name in the SSL certificate! An IP address won't work either. It can however be used to get your common name from the DNS. Find your IP address and issue the command

host <YOUR IP ADDRESS HERE>

The first line that reads Name: is what you should use as your common name!

Keep the file server.pem created here handy, we will need it later when setting up secure replication below.

Also, remember that since you're specifying the host name in the certificate (which is required), you must have one certificate for each of your LDAP server (if you're doing replication to other machines).

BerkeleyDB

Building and installing Berkeley DB

This software don't exists as Debian packages, so I had to make and install it my self. To do this, I just downloaded the tarball from the sleepycat website. I got version 3.0.55, and I see that the version on there site is now 3.2.9. I can't guarantee that that will work, but be my guest to try it. If it shouldn't work, you can get SleepyCAT v3.0.55 at my site. This is how to build the software after unpacking it in your favourite source directory.

cd build_unix
../dist/configure
make
make install

That's about all I have to say on the issue of installing Berkeley DB mostly because there's not much more to it! :).

UPDATE: With Debian GNU/Linux 2.3 (aka Woody) and later, BerkeleyDB 3.2.9 is availible in the libdb3 and libdb3-dev packages, so you won't really need to download and install BerkeleyDB from source. Just execute

apt-get install libdb3 libdb3-dev

and off you go...

MIT Kerberos V

Building MIT Kerberos V

Now, as promised I will here give you the configure parameters that the Debian packages are using:

--prefix=/usr
--enable-shared 
--with-ccopts="-g -O2 -D_REENTRANT"
--localstatedir=/etc
--mandir=/usr/share/man
--without-tcl

Then, just make all is executed.

Bugs in MIT Kerberos V, v1.2.1

NOTE1: As said above, there is a bug in all Kerberos implementations deriving from MIT KerberosIV (yes, that spells out 4, it's a very old bug!). The bug is that it have a temporary files race condition. For those that have a version lower than 1.2.2 and don't want to/can't upgrade, there's a patch to be found at the MIT Kerberos advisories site. For you that run Debian, please see the Building Cyrus SASL example how to make a Debian package with this patch.

NOTE2: Also, there have been discovered a buffer overflow vulnerability in the telnetd that is distributed with Kerberos 5, v1.2.2. See the URL http://www.securityfocus.com/bid/3064 for more information about this vulnerability. A patch for this bug can be found at the URL http://web.mit.edu/kerberos/www/advisories/telnetd_122_patch.txt.

NOTE3: Debian are now distributing MIT Kerberos v1.2.2 in it's unstable distribution, so just execute

apt-get update && apt-get upgrade

(if you are getting your packages from Internet, and not from CD that is). It should be installed into the testing and then the stable tree after a couple of weeks (if there isn't any serious bugs against the packages)...

Bugs in MIT Kerberos V, v1.2.2

NOTE1: A buffer overflow bug have been found in wu-ftpd (and therefor gssftpd which is the origin of part of the wu-ftpd). Have a look at the advisory at http://web.mit.edu/Kerberos/www/advisories/ftpbuf.txt. The patch is also located without the advisory text on the URL: http://web.mit.edu/Kerberos/www/advisories/ftpbuf_122_patch.txt.

Installing MIT Kerberos V

To prepare the Kerberos installation, one should read the Kerberos FAQ. This FAQ was a very good guide for me to learn (or at least give me a rough understanding of Kerberos :). Basically nothing in there needs to be done when using the Debian GNU/Linux packages. I just used the default ones, even though the version I installed first had a /tmp race condition bug. I have now upgraded to version 1.2.2-1 (the -1 is the Debian patch version). The installation is very straight forward, just answer the questions correctly :). However, there are some stuff that needs to be done before (or after if you like) the installation begins. You will need a working DNS system. And the KDC/KAdmin. server should really be on a separate machine, but I didn't have that luxury, so I installed it on the main system (I'll make a separate KDC/KAdmin/LDAP server later, but not now).

Configure Kerberos

Preparing the DNS for KerberosV

The DNS should be setup like follows to get full Kerberos network support. However, it seems like very few programs (OpenLDAP doesn't seem to) actually use the SRV entries, which is 'Server Location' entries. So if you don't want to/can't change the DNS, it is not required...

NOTE: I upgraded my Kerberos server (from 1.2.2 to 1.2.4) the other day, and I got the question if my DNS was listing the location of my KDC's (which it does) so maybe Kerberos is now using the SRV entries. I haven't verified what's the case here, it doesn't matter that much to me at the moment... :)

; IP addresses to the Kerberos/LDAP servers...
kerberos                IN      A       <IP ADDRESS OF YOUR 1st KERBEROS SERVER>
kerberos-1              IN      A       <IP ADDRESS OF YOUR 2nd KERBEROS SERVER>
kerberos-2              IN      A       <IP ADDRESS OF YOUR 3rd KERBEROS SERVER>
ldap                    IN      A       <IP ADDRESS OF YOUR 1st LDAP SERVER>
ldap-1                  IN      A       <IP ADDRESS OF YOUR 2nd LDAP SERVER>
ldap-2                  IN      A       <IP ADDRESS OF YOUR 3rd LDAP SERVER>
;
; Master setup
_kerberos               IN      TXT     "<YOUR KERBEROS REALM>"
_kerberos-master._udp   IN      SRV     0 0 88 kerberos
_kerberos-adm._tcp      IN      SRV     0 0 749 kerberos
_kpasswd._udp           IN      SRV     0 0 464 Kerberos
;
; Round-robin setup
_kerberos._udp          IN      SRV     0 0 88 kerberos
                        IN      SRV     0 0 88 kerberos-1
                        IN      SRV     0 0 88 kerberos-2
_ldap._tcp.<DOMAINNAME> IN      SRV     0 0 389 ldap
                        IN      SRV     0 0 389 ldap-1
                        IN      SRV     0 0 389 ldap-2

Don't forget to make sure that the revers look-up works. Much of my problems where that the KDC couldn't (wouldn't?) find my FQDN (Fully Qualified Domain Name => Host name + Domain name) for my IP address, or the other way around.

And what's this SRV stuff doing in there? That's kind'a cool feature in the BIND DNS server. See the page about specifying the location of services RFC for more about this.

The main KerberosV packages we will have to install on the KDC (Kerberos server), are the following packages.

krb5-kdc
krb5-admin-server
libkrb5-dev

To do this, all you have to do is execute (as root of course :) the command line

apt-get install krb5-kdc krb5-admin-server libkrb5-dev

and this will install and configure a KDC and Kerberos admin server. We will need the development package later on when we build SASL. Since I'm running Debian GNU/Linux, I just installed these default Debian packages, which also configured the stuff for me. What is also good to have is these packages (just add those you want at the end of the apt-get line. These packages should be installed on the Kerberos client. In my case, the KDC lives on my main server, so I installed these packages on the same system as the packages above. This is not recommended, but I had no choise.

krb5-doc
krb5-user
krb5-clients

If you like to offer Kerberos secured services like ftp, rsh, telnet etc, these are the packages you will also need to install (I did):

krb5-ftpd
krb5-rsh-server
krb5-telnetd

Now, apt is so very clever that it will download and install any packages that the above packages are dependent on. So, for example, if you are running with an older libc6 than the krb5 packages needs, apt will download and install (!) those for you to.

Kerberos config file

Now, there seems to be something wrong in some install script or other, because sometimes when I installed Kerberos, the file /etc/krb5.conf wasn't created correctly. I installed, unistalled back and fourth to try to figure out how to get this to work. I will here include the file I have, and it should work for most cases. As said, this seems to be a random problem, and I have not been able to successfully duplicate the problem, so double check the file for accuracy first.

<libdefaults>
        default_realm = <YOUR KERBEROS REALM>
        default_tgs_enctypes = des3-hmac-sha1 des-cbc-crc des-cbc-md5
        default_tkt_enctypes = des3-hmac-sha1 des-cbc-crc des-cbc-md5
        permitted_enctypes = des3-hmac-sha1 des-cbc-crc des-cbc-md5
        krb4_config = /etc/krb.conf
        krb4_realms = /etc/krb.realms
        kdc_timesync = 1
        ccache_type = 4
        forwardable = true
        proxiable = true

<realms>
        <YOUR KERBEROS REALM> = {
                kdc = kerberos.<YOUR DOMAINNAME>:88
                admin_server = kerberos.<YOUR DOMAINNAME>:749
                default_domain = <YOUR DOMAINNAME>
        }

<domain_realm>
        .<YOUR DOMAINNAME> = <YOUR KERBEROS REALM>

<logging>
        kdc = FILE:/var/log/kerberos/krb5kdc.log
        admin_server = FILE:/var/log/kerberos/kadmin.log
        default = FILE:/var/log/kerberos/krb5lib.log

<login>
        krb4_convert = false
        krb4_get_tickets = false

Create KerberosV realm

When the DNS is prepared and the packages installed, we need to create the realm data in the KDC. You will be notified by this by the Debian installer scripts. The command that needs to be executed are krb5_newrealm. It will create the stash file for you, and also create some service keys. This is what the script does (for those of you that aren't running Debian):

kdb5_util create -s
kadmin.local -q "ktadd -k /etc/krb5kdc/kadm5.keytab kadmin/admin"
kadmin.local -q "ktadd -k /etc/krb5kdc/kadm5.keytab kadmin/changepw"
/etc/init.d/krb5-kdc start || true
/etc/init.d/krb5-admin-server start ||true

The last two lines are however a little premature. We need some form of administrator user in the KDC to, so execute this line

kadmin.local -q "addprinc krbadm@<YOUR KERBEROS REALM>"

Also, while we are creating administrators, we will create a LDAP administrator principal. This principal will have full access to the LDAP database. For those of you that are migrating from OpenLDAP1 or OpenLDAP2 without SASL etc (or basically any other LDAP server I guess) will recognise this as the AdminDN (or rootdn as it's called sometimes).

kadmin.local -q "addprinc ldapadm@<YOUR KERBEROS REALM>"

Setting up KerberosV access rights

Also, some access lists should be installed/configured. In the file /etc/krb5kdc/kadm5.acl you should enter these lines:

kadmin/admin@<YOUR KERBEROS REALM>     *
<YOUR USERNAME>@<YOUR KERBEROS REALM>  *
krbadm@<YOUR KERBEROS REALM>           *
*/*@<YOUR KERBEROS REALM>              i

For me, the second line reads turbo@BAYOUR.COM * and that gives me full access to the database as my ordinary login. Might not be a good thing, but then you don't have to give out the kadmin/admin password to all of those that you want to have (full or partial) access to your kerberos system. See the Kerberos V5 Installation Guide:ACL file for other values you can have besides * and i.

As you can see in this ACL file, we have not listed the ldapadm principal we created above, only the krbadm. That's because we will separate the Kerberos administration from the LDAP administration. Even if you are running this system on only one machine, and you are alone in administrating this (and will be in a foreseeable future), I still recommend that you to separate the functions. Have you read the section LDAPv3, why bother. Remember the discussion about security? Let's not allow things to slip through the cracks in such a minor detail as two separate principals...

The default keytab depends on your installation, but for Debian GNU/Linux it is /etc/krb5.keytab. This file have to be (securely) copied to the LDAP server before being able to authenticate with SASL. I had a number of problems with a faulty keytab. The kvno didn't matchup for some reason. Most likely because I'm not (or at least wasn't) very good at Kerberos administration. See the section about Problems when the KVNO don't match up for ways of fixing/preventing this.

This about raps' up the Kerberos installation/configuration, now we can (re)start the KDC and Kerberos admin server.

Testing MIT Kerberos V

[I haven't written this part yet, please contribute!]

I can't really remember how I tested it, but if ktelnet/kftp/krsh/ksu works to/from you machine, it works. If not, take a look at the Kerberos FAQ.

Cyrus SASL

Building Cyrus SASL

This is the first package that we will have to modify, since the default's isn't good enough (we need GSSAPI). To get the full source code (inclusive the patches applied by the Debian maintainer etc), there's the tool apt-get. With the parameter source, it downloads the latest source code and unpacks it in the current directory. So, the source package for Cyrus-SASL is, you guessed it cyrus-sasl (Debian have lowercased package names over the board, that eases things). To double check, the command line is:

apt-get source cyrus-sasl

This is the second part. This one we need to modify a little from the default Debian GNU/Linux packages. The changes are the following, please edit the file debian/rules.

--enable-gssapi instead of --disable-gssapi

And all the option, for those of you that aren't running Debian GNU/Linux, are:

--prefix=/usr
--enable-static
--enable-login
--without-des
--without-rc4
--enable-gssapi
--disable-krb4
--mandir=/usr/share/man
--infodir=/usr/share/info

Bugs in Cyrus SASL, v1.5.24

There is a bug in the version 1.5.24 that makes interactive bind from ldapsearch fail if trying to connect with SSL/TLS. If you execute this command line (exchanging the <YOUR BASE DN>) after running kinit to get a Kerberos ticket:

ldapsearch -I -b "<YOUR BASE DN>" -H ldaps:///

If you then get the following error, you need the patch below.

ldap_sasl_interactive_bind_s: Unknown authentication method

NOTE: According to a message on the openldap-software mailing list, this was fixed some time ago in the CVS version of Cyrus SASL. So make sure that you need the patch before applying it! The version of the file plugins/gssapi.c in the cyrus-sasl source directory should be greater than 1.39, that's when it was fixed. So if you have a version higher than 1.39 you don't need to patch Cyrus-SASL. If you got the tarball from the FTP site, then you will need both these patches. Another thing, if you can't find a version number in the file noted above, then you're most likely not running the CVS version, so the patch is needed.

This is the patch you will have to apply:

diff -ur cyrus-sasl-1.5.24.orig/plugins/gssapi.c cyrus-sasl-1.5.24/plugins/gssapi.c
--- cyrus-sasl-1.5.24.orig/plugins/gssapi.c.orig        Wed Mar  7 19:42:31 2001
+++ cyrus-sasl-1.5.24/plugins/gssapi.c  Wed Mar  7 19:43:35 2001
@@ -1243,7 +1243,7 @@
 
        /* need bits of layer */
        allowed = secprops.max_ssf - external;
-       need = secprops.min_ssf - external;
+       need = secprops.min_ssf < external ? 0 : secprops.min_ssf - external;
        serverhas = ((char *)output_token->value)[0];
 
        /* if client didn't set use strongest layer available */

Also, there is a problem with the Debian GNU/Linux (and according to information on the OpenLDAP-Software list, in any place where you use pre-built binaries) that makes SASL 'forget' about the realm part in the login. The way to test this is by running slapd with options -d -1 and try a sasl bind. Then check the output from slapd. To save all the output that slapd is spewing out, use the command tee like this:

slapd -d -1 2>&1 | tee /tmp/output.txt

Then search in the file /tmp/output.txt for the parts that read:

slap_sasl_bind: username="u:[YOUR USER ID]" realm="[YOUR KERBEROS REALM]" ssf=[SOME NUMBER]
<== slap_sasl_bind: authzdn: "uid=[YOUR USER ID] + realm=[YOUR KERBEROS REALM]"

If you have the text realm=<YOUR KERBEROS REALM> in there, all is well, and you don't need the patch. If however, the realm is not listed there, then please apply this patch that I got from the mailing list:

diff -ur cyrus-sasl-1.5.24.orig/plugins/gssapi.c cyrus-sasl-1.5.24/plugins/gssapi.c
--- cyrus-sasl-1.5.24.orig/plugins/gssapi.c.orig        Fri Jul 21 04:06:52 2000
+++ cyrus-sasl-1.5.24/plugins/gssapi.c  Sun Dec 17 15:19:31 2000
@@ -592,6 +594,7 @@
        gss_buffer_desc name_without_realm;
        gss_name_t without = NULL;
        int equal;
+       char *realm = NULL;
 
        name_token.value = NULL;
        name_without_realm.value = NULL;
@@ -625,7 +623,8 @@
           without the realm and see if it's the same id (i.e. 
           tmartin == tmartin@ANDREW.CMU.EDU. If this is the case we just want
           to return the id (i.e. just "tmartin: */
-       if (strchr((char *)name_token.value, (int) '@')!=NULL)
+       realm = strchr((char *)name_token.value, (int) '@');
+       if (realm != NULL)
        {
            name_without_realm.value = (char *) params->utils->malloc(strlen(name_token.value)+1);
            if (name_without_realm.value == NULL) return SASL_NOMEM;
@@ -687,6 +686,14 @@
            strcpy(oparams->authid, name_token.value);
        }
 
+       if (realm != NULL)
+       {
+           realm++; /* skip '@' */
+           oparams->realm = (char *) params->utils->malloc(strlen(realm)+1);
+           if (oparams->realm == NULL) return SASL_NOMEM;
+           strcpy(oparams->realm, realm);
+       }
+
        if (name_token.value)
            params->utils->free(name_token.value);
        if (name_without_realm.value)

Applying this patch(-es) can be done by using patch. For example, the patch is saved in the file /tmp/gssapi1.patch. You would then use the following command (in the top directory of the cyrus sasl source).

patch -p1 < /tmp/gssapi1.patch

The patch can also be found at my site, GSSAPI patch 1 and GSSAPI patch 2. The author of the first patch comes originally from Nalin Dahyabhai <nalin@redhat.com>. Again, only do this if your plugins/gssapi.c version is lower than 1.39 (or if you're trying to compile SASL from the official tarball)!

Build the Cyrus SASL packages

Now you can start building the packages by executing the command line

debuild -uc -us -rfakeroot

Debuild is in the package devscripts, so just install that package by executing the command line

apt-get install devscripts

before building the package. To build the packages if you are not running Debian, you just execute make to build the software.

Installing Cyrus SASL

To make sure that the packages you just build don't get automatically upgraded when using the command

apt-get update && apt-get upgrade

etc, make sure to put the packages on hold. Easiest way to do that, is to go into dselect and press = on the line of the package. Another way to do this is to execute

echo <PACKAGENAME> hold | dpkg --set-selections

Do this after you have installed the packages :). Please also see the section about Bumping the Debian GNU/Linux package version on another way to avoid automatic upgrades of the newly made packages.

But before we install the SASL packages, you have to make sure that some libraries etc. that these libraries depend on is installed. To do this, first install these packages

libgdbmg1
libpam0g
libcomerr2
libkrb53

Then you can continue with installation of the SASL packages below

libsasl7
libsasl-modules
libsasl-bin

You do this by executing the command

dpkg -i libsasl7*.deb libsasl-modules*.deb libsasl-bin*.deb

To install the software if you are not running Debian, you execute the command make install. See the package libkrb53? Now you know why I asked you to install the Kerberos development packages. SASL must find krb5 on the system to allow you to use Kerberos V!

Testing Cyrus SASL

You will need to have a working Kerberos V system running. See the section Testing MIT Kerberos V for more about this. What you will have to do is get yourself two shells. Execute kinit in both and then in shell number one type

su -c ./sample-server -s ldap -p /usr/lib/sasl

And in the other one

./sample-client -s ldap -n <FQDN> -u <USERNAME> -p /usr/lib/sasl

Other than that, please follow the information outlined in the file testing.txt distributed with cyrus-sasl. You can find the file at this URL to, Testing the CMU SASL Library with the included sample applications if you prefer to have it through you favourite web browser.

OpenLDAP

Building OpenLDAP v2

This package have also been slightly modified to suite my needs. First the changes in the configure command line, please edit the file debian/rules.

--disable-cleartext instead of --enable-cleartext
--disable-rlookups  instead of --enable-rlookups
--with-tls          instead of --without-tls
--enable-kpasswd

To build against the Berkeley DB we built before, add these two lines before the configure line.

CPPFLAGS="-I/usr/local/BerkeleyDB.3.0/include" \
LDFLAGS="-L/usr/local/BerkeleyDB.3.0/lib" 

And all the options, for those of you that aren't running Debian GNU/Linux, are the following. These are the important ones you should have

--with-cyrus-sasl
--enable-slapd
--enable-crypt
--enable-spasswd
--with-tls
--enable-kpasswd

These are also some (optional) values you should add. Remove the options that you know that you definitely don't want. For example, the enable-ipv6 might be a bad idea sometimes...

--enable-debug
--enable-syslog
--enable-proctitle
--enable-cache
--enable-referrals
--enable-ipv6
--enable-local
--with-readline
--with-threads
--disable-cleartext
--enable-multimaster
--enable-phonetic
--disable-rlookups
--enable-wrappers
--enable-dynamic
--enable-dnssrv
--enable-ldap
--enable-ldbm
--enable-passwd
--enable-shell
--enable-sql
--enable-slurpd
--enable-shared

Bugs in OpenLDAP, v2.0.7

There might also bee needed to patch the file libraries/libldap/open.c from the openldap2 source directory. Read all about the reasoning behind this at the OpenLDAP ITS, bug 889. There's also a patch there for you that don't use Debian. If you however are using Debian, and you want the changes in the rules file and the discussed patch, you can apply this patch instead of doing it all by yourself. To apply this patch, see the Cyrus SASL bugs above or read the manual page for patch. This patch might not be needed on the OpenLDAP source you have, so verify that you need it before use! One way of doing this, is compile/install without it, and if ldapsearch, ldapadd, ldapmodify segfaults when trying to use the parameter -H, then you need it!

NOTE: These bugs have been fixed around 2.0.9 or so. At any rate, the latest version (at the time of this writing, 2.0.21) have it fixed, so there is no need to patch the files! Please have a look at the Updates section for more information.

diff -urN debian.orig/patches/004_libldap-open debian/patches/004_libldap-open
--- debian.orig/patches/004_libldap-open        Thu Jan  1 01:00:00 1970
+++ debian/patches/004_libldap-open     Wed Mar 14 22:13:52 2001
@@ -0,0 +1,19 @@
+diff -ur OPENLDAP_HEAD/libraries/libldap/open.c libraries/libldap/open.c
+--- OPENLDAP_HEAD/libraries/libldap/open.c     Wed Oct 18 11:53:53 2000
++++ ./libraries/libldap/open.c Tue Nov 21 20:37:04 2000
+@@ -329,8 +329,15 @@
+       if (ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
+               strcmp( srv->lud_scheme, "ldaps" ) == 0 )
+       {
++              LDAPConn        *savedefconn = ld->ld_defconn;
++              ++conn->lconn_refcnt;   /* avoid premature free */
++              ld->ld_defconn = conn;
++
+               rc = ldap_pvt_tls_start( ld, conn->lconn_sb,
+                       ld->ld_options.ldo_tls_ctx );
++
++              ld->ld_defconn = savedefconn;
++              --conn->lconn_refcnt;
+ 
+               if (rc != LDAP_SUCCESS) {
+                       return -1;
diff -urN debian.orig/rules debian/rules
--- debian.orig/rules   Wed Mar 14 22:10:41 2001
+++ debian/rules        Wed Mar 14 22:10:33 2001
@@ -34,11 +34,11 @@
 configure_args := --enable-debug --enable-syslog --enable-proctitle \
 --enable-cache --enable-referrals --enable-ipv6 --enable-local \
 --with-cyrus-sasl --with-readline --with-threads \
---enable-slapd --enable-cleartext --enable-crypt --enable-spasswd \
---enable-multimaster --enable-phonetic --enable-rlookups --enable-wrappers \
+--enable-slapd --disable-cleartext --enable-crypt --enable-spasswd \
+--enable-multimaster --enable-phonetic --disable-rlookups --enable-wrappers \
 --enable-dynamic --enable-dnssrv --enable-ldap --enable-ldbm \
 --enable-passwd --enable-shell --enable-sql --enable-slurpd --enable-shared \
---without-tls
+--with-tls --enable-kpasswd
 
 # FHS options
 configure_args += --prefix=/usr --localstatedir=/var --sysconfdir=/etc \
@@ -52,6 +52,8 @@
 $(STAMP_DIR)/pre-build-stamp: $(unpacked) $(patched)
        dh_testdir
        cd $(BUILD_TREE) && CFLAGS="$(CFLAGS)" \
+               CPPFLAGS="-I/usr/local/BerkeleyDB.3.0/include" \
+               LDFLAGS="-L/usr/local/BerkeleyDB.3.0/lib" \
                ./configure $(configure_args) --host=$(DEB_BUILD_GNU_TYPE)
        $(MAKE) depend -C $(BUILD_TREE)
        touch $(STAMP_DIR)/pre-build-stamp

You can also get the OpenLDAP v2 patch on papadoc.

When the possible patching is done, we will build the packages. Do this by executing the command

debuild -uc -us -rfakeroot

For those that aren't running Debian, execute the commands

make depend
make

Installing OpenLDAP v2

The packages you should install are the following:

libldap2
ldap-utils
slapd

You do this by executing the command

dpkg -i libldap2*.deb ldap-utils*.deb slapd*.deb

But before you can do this, you have to make sure that some libraries etc. that these libraries depend on is installed. To do this, execute the line

apt-get install libiodbc2

To install the software if you are not running Debian, you just execute the command

make install

For more information (in case of trouble building and installing OpenLDAP2 etc.), please see the OpenLDAP web site and/or the OpenLDAP FAQ-O-Matic:Quick Start Guide.

Configuring OpenLDAP v2

The Debian GNU/Linux installation script will guide you through most of the scripts and will also create the administration DN referred to in these files. This DN is mostly for backward compatibility with older clients, than can't do SASL/Kerberos binds.

Configure OpenLDAP to use the new SSL certificate

Changes to the OpenLDAP config file

Then it's just a matter of copying this file, server.pem to /etc/ldap and modify The OpenLDAP config file with these options:

TLSCertificateFile      /etc/ldap/server.pem
TLSCertificateKeyFile   /etc/ldap/server.pem
TLSCACertificateFile    /etc/ldap/server.pem
Changes to the OpenLDAP startup script

We have to make sure that slapd (the actual LDAP daemon/server) listens to port 636 which is the actual LDAP over SSL/TLS port. In the Debian GNU/Linux original startup script, we make this change:

--- slapd.orig  Fri Jul 27 08:53:39 2001
+++ slapd       Fri Jul 27 08:53:11 2001
@@ -21,7 +21,7 @@
     echo -n "Starting ldap server(s):"
     echo -n " slapd"
     start-stop-daemon --start --quiet --pidfile "$pidfile" \
-               --exec $DAEMON
+               --exec $DAEMON -- -h "ldap://0.0.0.0:$PORT/ ldaps://0.0.0.0/"
     replicas=`grep ^replica /etc/ldap/slapd.conf`
     test -z "$replicas" || (echo -n " slurpd" && start-stop-daemon --start \
                --quiet --name slurpd --exec $SLURPD)

That is, we have to make sure that SLAPD listens to ldaps (which is port 636). The PORT variable is set earlier in the script (at least in the Debian GNU/Linux version).You should have a line that read something like:

PORT=389

If you don't have this, either replace the $PORT part above with 389, or add the PORT=389 line above the slapd start lines...

The OpenLDAP config file

This could be a FAQ all on it's own, let's just include my config file, shall we?

# This is the main ldapd configuration file. See slapd.conf(5) for more
# info on the configuration options.

# Schema and objectClass definitions
include                 /etc/ldap/schema/core.schema
include                 /etc/ldap/schema/cosine.schema
include                 /etc/ldap/schema/inetorgperson.schema
include                 /etc/ldap/schema/nis.schema
include                 /etc/ldap/schema/krb5-kdc.schema
include                 /etc/ldap/schema/qmail.schema
include                 /etc/ldap/schema/qmailControl.schema
include                 /etc/ldap/schema/netscape-profile.schema
include                 /etc/ldap/schema/trust.schema
include                 /etc/ldap/schema/turbo.schema
# Some are extra schema's that I found on the 'Net...
# Want them? They can be found at http://www.bayour.com/openldap/schemas/

# Schema check allows for forcing entries to
# match schemas for their objectClasses's
schemacheck             on

# Where the pid file is put. The init.d script
# will not stop the server if you change this.
pidfile                 /var/run/slapd.pid

# List of arguments that were passed to the server
argsfile                /var/run/slapd.args

# Read slapd.conf(5) for possible values
loglevel                2048  # Only entry parsing errors

sasl-realm              <YOUR KERBEROS REALM>
sasl-host               <FQDN OF LDAP SERVER>
#sasl-secprops          none

#######################################################################
# ldbm database definitions
#######################################################################

# The backend type, ldbm, is the default standard
database                ldbm

# The base of your directory
suffix                  "<YOUR BASEDN>"

# Where the database file are physically stored
directory               "/var/lib/ldap"

# Save the time that the entry gets modified
lastmod                 on

# Indexes
index                   default pres,eq
index                   objectClass,uid,uidnumber,gidnumber,cn
index                   mail,mailalternateaddress,mailforwardingaddress eq

# Include the access lists
include                 /etc/ldap/slapd.access

# End of ldapd configuration file

In this file you will notice the option sasl-host. Remember the DNS setup? This is the host name and domain name of the host that your LDAP server is running on. It is not the FQDN of the kerberos server as I've stated in previous versions of this document. Sorry about that. In my case, this is egeria.bayour.com, because that was what I was entering into the SSL certificate. Don't forget the SSL/TLS certificate file options, which I showed you in Creating SSL certificate.

The OpenLDAP access file

I have all my access lists (ACL's) in a separate file (/etc/ldap/slapd.access). I'm still working on getting this to work properly so it's not perfect, but there you go.

# For Netscape Roaming  support, each user gets a  roaming profile for
# which they have write access to
access to dn=".*,ou=Roaming,dc=.*"
        by dn="<YOUR ADMIN DN>" write
        by dn="uid=ldapadm.+\+realm=<YOUR KERBEROS REALM>" write
        by dnattr=owner write
        by * none

# Some things should be editable by the owner, and viewable by anyone...
access to attr=cn,givenName,sn,krbName,krb5PrincipalName,gecos
        by dn="<YOUR ADMIN DN>" write
        by dn="uid=ldapadm.+\+realm=<YOUR KERBEROS REALM>" write
        by self write
        by users read

access to attr=loginShell,gecos
        by dn="<YOUR ADMIN DN>" write
        by dn="uid=ldapadm.+\+realm=<<YOUR KERBEROS REALM>" write
        by self write
        by * read

# Since we're using {KERBEROS}<PRINCIPAL>, we can't allow the user
# to change the password. They have to use the Kerberos 'kpasswd' to
# do this... But the admin can change (if need be).
# Please see krb5 userPassword attribute
access to attr=userPassword
        by dn="cn=admin,ou=People,dc=papadoc,dc=bayour,dc=com" write
        by dn="uid=ldapadm.+\+realm=<YOUR KERBEROS REALM>" write
        by anonymous auth
        by * none

# The  mail and mailAlternateAddress  should only  be readable  if you
# authenticate!
access to attr=mail,mailAlternateAddress,mailHost
        by dn="<YOUR ADMIN DN>" write
        by dn="uid=ldapadm.+\+realm=<YOUR KERBEROS REALM>" write
        by users read
        by * none

# Should not be readable to anyone, and only editable by admin...
access to attr=mailQuota,trustModel,accessTo
        by dn="<YOUR ADMIN DN>" write
        by dn="uid=ldapadm.+\+realm=<YOUR KERBEROS REALM>" write
        by self read
        by * none

# The admin dn has full write access
access to *
        by dn="<YOUR ADMIN DN>" write
        by dn="uid=ldapadm.+\+realm=<YOUR KERBEROS REALM>" write
        by * read

Notice the

by dn="uid=ldapadm.+\+realm=<YOUR REALM>" write

That's the Kerberos principal you want write access to the database as. This principal was created in the Create KerberosV realm section.

But there seems to be another bug in the Debian SASL packages. According to information on the openldap-software mailing list, the problem don't exist in the tarball from Cyrus home page. See the section about the SASL patch - Realm for more about this.

One important note about the by dn entries above. They use regexp, so make sure that you protect any dots in the realm, like this

access to * by dn="uid=ldapadm.+\+realm=BAYOUR\.COM" write

or

access to * by dn="uid=ldapadm.+\+(realm=BAYOUR\.COM)" write

Creating a LDAP service key

To let OpenLDAP/SASL connect to the KDC, we need to add a LDAP service key into the KDC. To do this, use the command kadmin or kadmin.local like this:

kadmin.local -q "addprinc -randkey ldap/<FQDN>@<YOUR KERBEROS REALM>"
kadmin.local -q "ktadd ldap/<FQDN>"

Populate the database to allow simple bind as user

If you starting out fresh with this project, you will have to read up on how to create a database on the openldap database creation and maintenance tools page. When you understand this, it's time to specify the special object classes and attributes that makes this whole LDAPv3 thing tick. The object class krb5Principal specify that the attribute krb5PrincipalName is a must and that the cn and krb5PrincipalRealm attributes is optional. What this means, is that we use the following LDIF snippet on each of our users:

objectClass: krb5Principal
krb5PrincipalName: turbo@<MY KERBEROS REALM>
cn: Turbo Fredriksson

The cn means Common Name, and in this case it's my full name (yes, my name really IS turbo! :).

These attributes and object classes are defined in the krb5-kdc.schema file distributed with OpenLDAP2. The other object classes (krb5KDCEntry and krb5Realm) are not used in this context, so ignore them :).

Modify the LDAP database to allow simple bind as user.

If you already have a database, but are using some other means of storing the passwords, you will have to do some minor modifications to the database. For example, my production server, which is a version 1.2.11 have the passwords in the LDAP database as '{crypt}CRYPTEDPW', and is using libpam-ldap (and for migration purposes libpam-krb5 which is NOT to recommend in a shared network environment since it binds in clear text) to authenticate the users on all services (ssh/imap/pop/ftp etc). Now, Quite naturally I wanted to use that database, so I first did a dump of the original database with ldbmcat (to convert it into an LDIF file) and then on the new server, slapadd to create the database. This was a big problem, since OpenLDAP2 is much more strict about the existence of a proper schema for the objectClasses etc. See LDAP schemas on Papadoc for the schema's that I have (I found most of them on the Internet so don't blame me if they are a little out of date :).

Before loading the database into the new server, I had to change all the userPassword attributes. This is where the --enable-kpasswd comes into play. The password should be {KERBEROS}<USERS PRINCIPAL> like this (my entry):

dn: uid=turbo,ou=People,<MY BASEDN>
replace: userPassword
userPassword: {KERBEROS}turbo@<MY KERBEROS REALM>

This have to be done for all the users to allow them to authenticate! This only works if you have compiled OpenLDAP2 with the configure option --with-kpasswd, and what that do is making slapd ask the Kerberos server if the password corresponds with the password for the Kerberos principal turbo@<MY KERBEROS REALM>. What this do, is it's telling the OpenLDAP2 server (slapd) to check the password in the Kerberos server. Since there is no password in the LDAP database any more, we have to make sure that the user can't change there password with either ldappasswd or via PAM. Therer for, please have a look at the The OpenLDAP access file again (especially the 'access to attr=userPassword' section.

Now, just to clarify some things (because it will look a little strange). If you do the modifications above, and then do a search (ie, retrieving) the userPassword value from the database, it will look a little garbled:

userPassword:: e2NyeXB0fUlNRDR0cmxiaUdFVVU=

This is nothing to worry about. It's simply base 64 encoded (this reads {KERBEROS}turbo@BAYOUR.COM after decoding).

Notes about 'userPassword: {KERBEROS}'

The reason for using userPassword: {KERBEROS}PRINCIPAL is so that we can allow simple binds with the password in the Kerberos database. This should not really be done, since if we do a simple bind without SSL/TLS, we're opening up the Kerberos database. We're using Kerberos so that we get a secure system, remember?!.

So simple binds would only be allow if it's protected with SSL or TLS. If you have no interest in allowing simple binds (note, this is not SASL bind!), then don't use the userPassword entry at all. If you only have interest in allowing SASL binds, this entry can be left out completely. If, for some reason, you have clients that can't do SASL binds (Qmail-LDAP comes to mind), then don't have the password in the Kerberos database, but in LDAP with either {CRYPT} or even better {SSHA}. Using the command slappasswd, you can create a scheme to be inserted into the database. This way, you won't accidentally compromise your Kerberos database security.

Testing OpenLDAP v2

In the ldapsearch commands below, I use localhost for the name of the LDAP server. I got one mail from Will Day on the OpenLDAP-Software mailing list, saying that this didn't work for him. He had to exchange localhost to the FQDN of the LDAP server instead. The reason for this is most likely because it can't get a ticket for ldap/localhost@<KERBEROS REALM>. To avoid that, just enter a ldap/localhost@<KERBEROS REALM> service key as well as the ldap/<FQDN>@<KERBEROS REALM>. Have a look at Creating a LDAP service key below how to do that. So, if the commands don't work as shown here, please try that.

Also, I'm specifying port 389 here. You might not need that at all, since that's the default port of the LDAP server. I only list that here, because while setting all this up for the very first time, I ran a OpenLDAP1 server on port 389, and my new OpenLDAP2 server on port 3389. This server is now my main LDAP database.

Testing OpenLDAP, simple/anonymous bind

The first thing is probably to check if a non SASL/SSL/TLS (that is, a simple bind) works

ldapsearch -h localhost -p 389 -x -b "" -s base -LLL supportedSASLMechanisms

You should get something like this

supportedSASLMechanisms: PLAIN
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: ANONYMOUS
supportedSASLMechanisms: GSSAPI

The important stuff here is the last line! If you don't have GSSAPI listed (the other ones doesn't really matter for us at this moment, although you should have ANONYMOUS in addition to GSSAPI), something is wrong, and you should go back to Building OpenLDAP v2 (or maybe you need to go back to Building Cyrus SASL) and do it right this time. On my production server, I have now disabled some of these mechanisms, so the only one I get is GSSAPI. This is perfectly ok, since I only want/need SASL (GSSAPI) binds.

Testing OpenLDAP, simple/anonymous bind, with SSL/TLS

If the search for supported SASL mechanisms went well, let's continue with the next step. Let's try to do a simple bind, but with SSL and TLS. The first command tests TLS, and the second one SSL (notice the parameter -ZZ in the first command and ldaps:/// in the second?).

ldapsearch -H ldap://<FQDN OF LDAP SERVER>/ -p 389 -x -b "" -s base -LLL -ZZ supportedSASLMechanisms
ldapsearch -H ldaps://<FQDN OF LDAP SERVER>/ -x -b "" -s base -LLL supportedSASLMechanisms

You should get the same stuff as above back, only this time it is sent to you encrypted from the LDAP server. You can double check this by using a packet sniffer. The reason we have to enter the full name of our LDAP server for these two commands (instead of just ldap:/// or ldaps:///) is because in newer OpenLDAP, the certificate verifications is much stronger. It requires the FQDN one connects to matches the one in the certificate. In my example (see the section about Creating SSL certificate) the commands would look like:

ldapsearch -H ldap://egeria.bayour.com/ -p 389 -x -b "" -s base -LLL -ZZ supportedSASLMechanisms
ldapsearch -H ldaps://egeria.bayour.com/ -x -b "" -s base -LLL supportedSASLMechanisms

Testing OpenLDAP, using your Kerberos ticket

Now let's try out a SASL bind. Exchange the -x above to -I (uppercase i) like below. Just press enter when you get the prompt Please enter your authorisation name:.

ldapsearch -H ldaps:/// -I -b "" -s base -LLL supportedSASLMechanisms

Anything? Nope, you should get back:

ldap_sasl_interactive_bind_s: Local error

This is a bug (or maybe more correctly, 'missing feature' :) in SASL (it doesn't return the correct error codes). There is no known fix for this yet. To get around it, execute the command kinit and try again. The lines above, with -x replaced with -I should return something like:

SASL SSF: 56
SASL installing layers
dn:
supportedSASLMechanisms: PLAIN
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: ANONYMOUS
supportedSASLMechanisms: GSSAPI

Here DES (56 bit key lengh for symmetric cryptography) is used to encrypt the data stream. That is, the transfer of the information to you isn't encrypted, but the actual bind (the password and user/authorisation name) is. Hmm, wonder if this is true... I've heard 'rumors' on some lists that SASL actually ARE encrypting all communication between you and the LDAP server. Ah, well. Better safe than sorry, use -H or -Z.

Testing OpenLDAP, using your Kerberos ticket, with SSL/TLS

Please verify that a SSL and TLS works with SASL to by using -ZZ and -H parameters to the above ldapsearch command line. The difference between -Z and -ZZ is that the later requires the operation to be successful.

Testing OpenLDAP, simple user bind, with SSL/TLS

Now, if all the changes to the database (see how to populate the database and/or modify the LDAP database) have been done and all the above tests work, let's try to search the database as yourself again, but this time doing it with a simple bind (-x to ldapsearch). To make absolutely sure that it doesn't try to use the Kerberos ticket you got with kinit above, execute kdestroy. Just to be on the safe side when testing here, mind you :). Here we go, all in one line:

ldapsearch -x -D 'uid=turbo,ou=People,<MY BASEDN>' -W -b "" -s base -LLL -H \
ldaps://<FQDN OF LDAP SERVER>/ supportedSASLMechanisms

Enter the password when prompted. This command should return the same thing as the previous commands. Remember, you should enter the password for your KerberosV principal. If it didn't take the Kerberos password, you would get this back:

Enter LDAP Password: 
ldap_bind: Invalid credentials

I worked for quite some time (about 4-5 days) to get this part to work. I had no luck. Then, all of a sudden it worked, and I'm not quite sure why. I am however quite sure that it have something to do with the order the ACL's for userPassword is arranged. OpenLDAP v2.0 is a LOT more picky about the order of the ACL's than the 1.3 version(s) where (where my config/access file originates from). See my OpenLDAP access file of how it looks when it works. Take a extra look at the section that starts with:

access to attr=userPassword

NOTE: The parameters -D, -W and -w is not used when using SASL (unless you want a simple bind, which you normally wouldn't). You use -I (uppercase i), -U and -X to use SASL bind. For anonymous and/or simple binds, one have to use the option -x.

If all the above searches work, you might want to try searching for data under your base DN, and also do modifications etc, just to double check that everything works as it's supposed to. The biggest problems I had with all this, must be the ACL's! Have a second look at The OpenLDAP access file.

Setting up secure replication

One of the main points (for me at least) by using SASL, Kerberos and SSL/TLS is so that we can have a secure/encrypted authentication and communication between the master and slave LDAP server(s). To try this out, I will demonstrate how you can (and should?) have a slave server running on localhost. The reason we want to do this, is so that when doing backups of the LDAP database, we don't need to take down the master database, only the read-only replica, which means that we don't have any downtime on the LDAP server.

Replication configuration, slave server

The first thing we do, is we create the config file for the slave server. This is basically the exact same config file as The OpenLDAP config file. The differences though, is that the database is located in another directory. Preferably we should set the database to read only, but it doesn't seem to work. We will instead use ACL's to limit the access (as much as I can, with the limited knowledge of OpenLDAP2's ACL structure :).

directory       "/var/lib/ldap.backup"
include         /etc/ldap/slapd.access.backup
updatedn        "uid=replicator + realm=<YOUR REALM>"

It is important that the updatedn directive is after any database directives. This usually means at the very bottom of the file. Also, the updatedn is not a regexp, so it have to be specified as is.

To make sure that any modification to a slave server isn't possible but instead redirected to the master, the configuration directive updateref is used.

updateref ldaps://master.domain.com

Note though, that it's important to only add this after everything works as expected, because all changes will be redirected to the master LDAP server.

Other than that, we will run the slave server on other ports than the master. That's since we are running both on the same machine, and we can't bind both of them on the same port (unless you make it bind to different IP addresses, but that's nothing I will go into here). There for we add some more options to the command line. You can use the master's start script, modify it by running slapd like this:

PORT=3391 /usr/sbin/slapd \
     -h "ldap://0.0.0.0:$PORT/ ldaps://0.0.0.0:`expr $PORT + 1`/" \
     -f /etc/ldap/slapd.conf.backup

That will start the non-SSL/TLS port on 3391, and the SSL/TLS port on 3392.

Replication configuration, master server

The modifications to the master database's configuration, is the location of the slave. This is what we will add to the database definition in The OpenLDAP config file:

replica         host=localhost:3391
                tls=yes
                bindmethod=sasl
                saslmech=GSSAPI
replogfile      /var/lib/ldap/replog

It is important that this replication setup is entered after any database directives. This usually means at the very bottom of the file.

Please see the OpenLDAP 2.0 Administrator's Guide:Replication and the manual page for slapd.conf for more about this.

Creating a replication principal

To be able to use GSSAPI/Kerberos V with replication, we will need to create a service key that we will use for authentication and extract that into a keyfile. The principal I have chosen here is replicator, but you can essentially choose any principal you like, as long as use use the same principal in the access list on both the master and the slave server. To create such a principal, we execute the following commands:

kadmin.local -q "addprinc -randkey replicator@<YOUR KERBEROS REALM>"
kadmin.local -q "ktadd -k /etc/krb5.keytab.slurpd replicator"

Make sure that the keytab file (/etc/krb5.keytab.slurpd in this example) is secure. That is, transfer it safely to the slave and master LDAP server (using for example scp or kscp). Also make sure it is not readable for anyone else than the user slapd is running as.

If this file is compromised (obtained by any arbitrary user), then your whole LDAP database will have to be considered compromised!


Automatically getting a ticket before starting slurpd

Since we are using SASL/KerberosV to do the replication authentication, we must ensure that slurpd have a Kerberos ticket before starting. We must also 'remember' the location of the ticket file, so that it can be removed when shutting down slurpd. To do this, we use the LDAP service key we created above, like this:

kinit -r 7d -k -t /etc/krb5.keytab.slurpd replicator@<YOUR KERBEROS REALM>

This line will have to be inserted into the slapd/slurpd start script, just before slurpd is started. To make sure that the ticket gets removed/destroyed when no longer needed (ie, when slurpd is shutdown), we issue the command kdestroy just after slurpd have been stopped.

This results in the following start scripts (for starting slurpd):

replicas=`grep ^replica /etc/ldap/slapd.conf`
if [ ! -z "$replicas" ]; then
    KRB5CCNAME=FILE:/var/run/slapd.krbenv
    echo -n "Getting ticket for replicator: "
    kinit -k -t /etc/krb5.keytab.slurpd replicator@<YOUR KERBEROS REALM>
    echo "done."

    echo -n "Starting LDAP replication daemon: "
    /usr/sbin/slurpd
    echo "done."
fi

This is the stopping part:

replicas=`grep ^replica /etc/ldap/slapd.conf`
if [ ! -z "$replicas" ]; then
    echo -n "Stopping LDAP replication daemon: "
    killall slurpd > /dev/null 2>&1
    echo "done."

    KRB5CCNAME=FILE:/var/run/slapd.krbenv
    echo -n "Removing Kerberos ticket: "
    kdestroy && rm /var/run/slapd.krbenv
    echo "done."
fi

Keeping replication ticket updated

To make sure that there always is a ticket for the replicator, we will have to execute the kinit line above every now and then from cron. How often this should happen, depends on how long-lived the ticket is. To find that out, we issue the command kadmin (or kadmin.local) like this:

kadmin.local -q "getprinc replicator" | grep "^Maximum ticket life:"

In my case, it will return:

Maximum ticket life: 0 days 10:00:00

So I will have to renew the ticket at least every ten hours. To be on the safe side, I'll do it every nine hours. The entry we will put into /etc/crontab is:

# Making sure that the LDAP replication have a valid ticket
KRB5CCNAME=FILE:/var/run/slapd.krbenv
0 */9 * * * root test -e /var/run/slapd.krbenv && kinit -R

You can read more about running and getting tickets in shell scripts untended at the Kerberos FAQ:Shell scripts.

There is a way to specify a longer life time when creating the principal (-maxlife) but I haven't figured out exactly how to specify the time. I keep getting Invalid date specification all the time.

UPDATE: The maximum lifetime of a ticket can, in kadmin or kadmin.local be specified like

-maxlife "4 days"
-maxlife "4 hours"

etc...

Give the replicator access to the database

We must give the replicator principal access to write to the database. To do this, we create this access file instead of The OpenLDAP access file we had for the master server (this file is named /etc/ldap/slapd.access.backup in the slave server replication configuration above). The reason it's much simpler is because it's read-only, and should contain a online backup of the database, therefor there is no need for anyone else than replicator to be able to read/write to the slave.

access to attr=cn,givenName,sn,krbName,krb5PrincipalName,loginShell,gecos,mail,
        mailAlternateAddress,mailHost,mailQuota,uidNumber,gidNumber,homeDirectory
        by dn="uid=replicator.+\+realm=<YOUR KERBEROS REALM>" write
        by users read
        by * none

access to attr=userPassword,ldapPassword,clearTextPassword
        by dn="uid=replicator.+\+realm=<YOUR KERBEROS REALM>" write
        by * none

access to *
        by dn="uid=replicator.+\+realm=<YOUR KERBEROS REALM>" write
        by * read

We should really not have read access at all (by users read and by * read), but for some reason (which elude me) it doesn't work otherwise...

Building miscellaneous software

Concurrent Version System

Building CVS

The version I did this with was v1.11-0.1. One can now authenticate and encrypt using the GSSAPI network security interface. For details, see the Cederqvist's description of specifying :gserver: in CVSROOT, and the -a global option.

Configure options

To do this, we need to build with the following options to configure:

--with-gssapi=value     GSSAPI directory
--enable-encryption     enable encryption support

For non-Debian systems, these are the full configure opions:

--prefix=/usr
--mandir=/usr/share/man
--infodir=/usr/share/info
--with-gssapi
--enable-encryption

How to build and install? Haven't you paid attention? :) Please go back to the Building Cyrus SASL section again...

With Krb4 option

There's the --with-krb4=value to configure in this case, but as you can see that is for Kerberos IV, and that isn't fully compatible with MIT Kerberos V. There is however a krb524d daemon that takes care of converting a Kerberos IV request to a Kerberos V. But that's quite pointless, since we are already using GSSAPI with our Kerberos V server. From what I can tell, you should only run the krb534d daemon if you don't have any other choice. That is, if there weren't any --with-gssapi option here, we'd go for the --with-krb4, and made sure that our converter daemon was running.

Creating a CVS service key

To be able to use GSSAPI/Kerberos V with CVS, you will have to add the appropriate service key into the Kerberos database:

kadmin.local -q "addprinc -randkey cvs/<FQDN>@<YOUR KERBEROS REALM>"
kadmin.local -q "ktadd cvs/<FQDN>"

As you can see, the service name for CVS, are... Right, cvs!

Cyrus IMAP/POP

This is currently unverified by me, but this is supposed to be the way it's done...

Building Cyrus IMAP and POP3 server

To have the Cyrus IMAP and POP3 server use GSSAPI (SASL) to authenticate the user, we need the source of the Cyrus IMAPd/POP3d package (apt-get source cyrus-imapd). And to build, these are the options to configure:

[I'm currently trying this out, come back in a few days]

For non-Debian systems, these are the full configure options:

[I'm currently trying this out, come back in a few days]

Configure Cyrus IMAP and POP3 server

See Cyrus IMAP/POP Howto:Cyrus IMAP Configuration and imapd.conf(5) for more about this.

Creating a IMAP/POP3 service key

To be able to use GSSAPI/Kerberos V with IMAPd/POP3d, you will have to add the appropriate service keys into the Kerberos database:

kadmin.local -q "addprinc -randkey imap/<FQDN>@<YOUR KERBEROS REALM>"
kadmin.local -q "addprinc -randkey pop/<FQDN>@<YOUR KERBEROS REALM>"
kadmin.local -q "ktadd -k /etc/krb5.keytab.cyrus imap/<FQDN>"
kadmin.local -q "ktadd -k /etc/krb5.keytab.cyrus pop/<FQDN>"
chown cyrus /etc/krb5.keytab.cyrus

The keytab above is used in the wrapper needed for GSSAPI/KerberosV support:

#!/bin/sh

KRB5_KTNAME=/etc/krb5.keytab.cyrus
export KRB5_KTNAME
exec /usr/sbin/imapd.real $@

LibPAM-LDAP and LibNSS-LDAP

Building and installation

Downloading source

Basicly the only thing that needs to be done with these two packages are rebuilding (ie, configure and make) them, to get SSL/TLS support. For those of you that are running Debian GNU/Linux, execute this command

apt-get source libpam-ldap libnss-ldap

and the source of the two packages will be downloaded and unpacked in the current directory.

Building packages

To create the two Debian GNU/Linux packages, execute this command (we only have to rebuild them to have them recognize that we have the installed OpenSSL development package files)

find -maxdepth 1 -type d -name 'lib*ldap-*' -exec sh -c 'cd {} && debuild -rfakeroot -uc -us' \;

Install the newly made packages

Now it's just a matter of executing the following command to install them:

dpkg -i lib*ldap_*.deb

SAMBA

This is currently unverified by me, but this is supposed to be the way it's done...

Building Samba/Samba-TNG

Wed, May 30, 2001

Have compiled samba-2.2.0.final with the following options. I'm currently trying to configure samba. Using 'security = user' and 'encrypt passwords = no' don't work at all, and using encrypted password don't either (it bypasses the auth mechanisms).

--with-krb5
--with-ssl
--with-sslinc=/usr/include/openssl

According on a mail on the kerberos mailinglist, Microsofts Step-by-Step Guide to Kerberos 5 (krb5 1.0) Interoperability should be interesting to read... You be the judge, I haven't bothered to read it fully yet :).

Fri, Jun 1, 2001

It seems that the LDAP support in samba 2.2 isn't working at all. Have downloaded samba TNG via CVS, hopefully that will work...

Compile options
--with-fhs
--prefix=/usr
--sysconfdir=/etc
--with-privatedir=/etc/samba
--with-lockdir=/var/state/samba
--localstatedir=/var
--with-netatalk
--with-smbmount
--with-pam
--with-syslog
--with-sambabook
--with-utmp
--with-readline
--with-krb5
--with-ssl
--with-sslinc=/usr/include/openssl
--with-ldap
--with-utmp
Make string
make SMBLOGFILE=/var/log/smb NMBLOGFILE=/var/log/nmb all smbtorture rpctorture debug2html

OpenAFS

I have this working just fine on my live server, and it have been working great (better than expected!) for about three months now. From the occasional glitch when I started to understand what exactly AFS is, I now have all my users, my web directory and whole of my FTP support directory on AFS.

There's many good things about AFS, and one that I've started to like more and more, is that root is no longer almighty! Root have (at least default) absolutely NO rights in AFS space! It's all about tickets (Kerberos V) and tokens. The ACL (Access Control List) of the directory decide who have access to what, not the system UID (User Identification Number).

AFS also come with 'replication support' as standard, so adding more servers is a good thing. And easy to, from what it seems.

To get OpenAFS up and running with Kerberos V (OpenAFS only works with Kerberos IV as standard), there is some additional software's necessary besides the OpenAFS sources. These are the OpenAFS PAM module and the the special OpenAFS/KerberosV support software's.

Getting OpenAFS and the associated PAM/KRB5 softwares to compile under Debian GNU/Linux 2.2 (code name Potato) have been proven to be very difficult. There's a lot of build dependencies that have to be fulfilled and very few of the packages required exists for Potato. I have therefor left out the building of all these packages. If you really want to build for Potato, you will have to figure out how to build those yourself.

OpenAFS

Building OpenAFS</