AUTHOR: Randy McMurchy DATE: 2004-05-16 LICENSE: Creative Commons Attribution-NonCommercial-ShareAlike License http://creativecommons.org/licenses/by-nc-sa/1.0/ SYNOPSIS: Configuring PAM/LDAP/SASL/Kerberos as a secure NIS+ replacement DESCRIPTION: This hint provides instructions to configure various BLFS packages and other support software to create a secure and centralized network information service similar to functionality provided by NIS+. This hint also provides instructions to configure Glibc database files for primary nameservice and/or use during times when the LDAP database is unavailable. ATTACHMENTS: http://www.mcmurchy.com/lfs/sign.sh http://www.mcmurchy.com/lfs/slapd.conf http://www.mcmurchy.com/lfs/dummy.ldif http://www.mcmurchy.com/lfs/nss_db-2.2-update-1.patch http://www.mcmurchy.com/lfs/nss_updatedb-1-FHS_compliance-1.patch PREREQUISITES: This hint combines the functionality of many packages. The packages I used are listed here, and installation notes for each package will be found in the body of the hint. I've listed the following packages with their version numbers as this combination is known to behave correctly when properly configured. vixie-cron-3.01 tcpwrappers-7.6 readline-4.3 xinetd-2.3.13 OpenSSL-0.9.7d Berkeley DB-4.1.25 NTP-4.2.0 cracklib-2.7 Linux-PAM-0.77 Heimdal-0.6.2 (MIT Kerberos would probably work also, though not tested) pam_krb5-1.3-rc7 Cyrus-SASL-2.1.18 OpenLDAP-2.1.30 nss_ldap-217 pam_ldap-169 We'll use some other software packages along the way as we perform the configuration tasks, import data into the LDAP database and create the offline database files. MigrationTools-45 nss_db-2.2 nss_updatedb-1 pam_ccreds-1 HINT: ========= CONTENTS: ========= 1. Introduction 2. Software Installation vixie-cron-3.01 tcpwrappers-7.6 readline-4.3 xinetd-2.3.13 OpenSSL-0.9.7d Berkeley DB-4.1.25 NTP-4.2.0 cracklib-2.7 Linux-PAM-0.77 Heimdal-0.6.2 pam_krb5-1.3-rc7 Cyrus-SASL-2.1.18 OpenLDAP-2.1.30 nss_ldap-217 pam_ldap-169 MigrationTools-45 nss_db-2.2 nss_updatedb-1 pam_ccreds-1 3. SSL Certificates Introduction Create an RSA Private Key Create a Server CSR Create a Certificate Authority Sign the Server CSR Encrypted or Unencrypted Key Installing the Certificates Final Notes on SSL Certificates 4. Software Configuration Introduction Create the ldap User and Group Set the Permissions on the SSL Certificates Create a Kerberos LDAP Service Principal Setting Permissions and Ownership of Remaining Files Configure /etc/openldap/slapd.conf Configure /etc/openldap/ldap.conf Configure /etc/ldap.conf Configure /etc/nsswitch.conf Configure the LDAP Backend Database Client only configuration Configuration Summary 5. Initial Population of the LDAP Directory Standard Warning Start the slapd Daemon Test Access to LDAP Import the LDIF File 6. Testing the Installation Using ldapsearch Modifying Entries in the Directory Resuming the ldapsearch Tests Using System Tests Logging in With the Dummy User 7. Configuring Linux-PAM 8. Completing the LDAP Directory Population 9. Issues, Gotchas and Other Sundry Items 10. To Do List 11. Closing ================ 1. INTRODUCTION: ================ These instructions should allow you to configure a Linux system to use OpenLDAP, in conjuction with Linux-PAM, Cyrus-SASL and Heimdal Kerberos 5, to centralize your network related flat file information. The configured system(s) can then be accessed by all the other systems on the network to retrieve this data. This solution provides capabilities similar to those provided by NIS+, although much more secure. Just about any network flat file information can be stored in OpenLDAP, and become available for network access. For that matter, just about any type of information can be stored in LDAP and be made publically available. This hint is more geared towards storing the user and group information, normally contained in /etc/passwd and /etc/group, in the LDAP database. The user and group information will be stored in LDAP, the user passwords will be stored in a secure Kerberos database. Additionally, by resurrecting libnss_db and using cron to keep the db files updated, you can have LDAP user and group information locally. This has a two-fold benefit. One, you can configure nameservice lookup to search the local db files before having to go across the network to fetch LDAP info, and two, LDAP user/group information is available when you don't have access to LDAP. Originally, the design of this project was to store the Kerberos passwords inside the LDAP database. This would have been the last step of the process. Maybe after I become more comfortable (and trusting) of the LDAP access control lists, I'll do this. For now, however, I've decided to have separate LDAP and Kerberos databases. This may be desireable in the long run as having the databases separated allows them to be run on different servers. For the purpose of this hint, you may have the master Kerberos KDC and LDAP databases on the same server, or on separate servers, it won't matter to the setup. This decision is yours. After completion of this hint, you'll have secure, centralized network information available to clients and other network servers, even during times when the LDAP server is unavailable for whatever reason. End users might see a small difference in day-to-day activities as they may have to use the Kerberos authentication tools. The learning curve for Kerberos authentication is almost nil, as typical Kerberos authentication simply requires the end user to acquire a TGT (ticket-granting-ticket) authentication ticket by using the "kinit" command. The setup described in this hint uses Linux-PAM to call the Kerberos authentication mechanism and transparently acquire the TGT. After acquiring the TGT, end users accessing kerberized network resources do not have to authenticate. For non-kerberized resources, normal authentication methods are used. If all this sounds like something you want/need for your network, simply follow the instructions in this hint. You should get there. Nothing in this hint is complicated or requires special sysadmin skills. All the software required for this setup is publically available, much of it installed using instructions in the BLFS book. ========================= 2. SOFTWARE INSTALLATION: ========================= The software packages listed here are the ones I used. Some may be substituted with similar packages. Some may be omitted. I'll try to outline what can be substituted, what can be omitted and what is mandatory. Using the packages shown below should result in a reliable, secure and stable centralized network nameservice method. Additionally, when the software is installed differently depending on what type of machine (server, client) it's installed on, I'll identify the differences. --------------- vixie-cron-3.01 --------------- Any scheduling package you desire should work. The purpose of the scheduling software is to update the offline nameservice database files. If you don't plan on creating offline nameservice, you won't need a scheduling package. I use Paul Vixie's old cron package as it most closely resembles the cron daemons I've been using for years and years. There's a very fine hint written by Jim Gifford covering the installation of vixie-cron. See: http://www.linuxfromscratch.org/hints/downloads/files/vixie-cron.txt --------------- tcpwrappers-7.6 --------------- I use tcpwrappers for rudimentary IP authentication. It is not required for the purposes of this hint. I also use IPTables for additional security, however, the configuration of IPTables is beyond the scope of this document. Should you desire to use tcpwrappers, see installation instructions at: http://www.linuxfromscratch.org/blfs/view/cvs/basicnet/tcpwrappers.html If you use tcpwrappers, you may want to wait until after you've completed this hint to install your /etc/hosts.deny file. For example, "make test" will fail during the testing of OpenLDAP unless you configure the slapd daemon in /etc/hosts.allow before the test if your /etc/host.deny file is configured to disallow running slapd. ------------ readline-4.3 ------------ The readline package is an optional dependency of several of the mandatory packages. I installed it and configure its use for each package that supports it. For installation instructions, see: http://www.linuxfromscratch.org/blfs/view/cvs/general/readline.html ------------- xinetd-2.3.13 ------------- The xinetd package is touted as "a secure replacement for inetd". I use it instead of inetd. For installation instructions, see: http://www.linuxfromscratch.org/blfs/view/cvs/server/xinetd.html -------------- OpenSSL-0.9.7d -------------- OpenSSL is mandatory for the cryptographic functions required by other packages. For installation instructions, see: http://www.linuxfromscratch.org/blfs/view/cvs/general/openssl.html ------------------ Berkeley DB-4.1.25 ------------------ Berkeley DB is mandatory. Since beginning this project, the BLFS book has been updated to BDB-4.2.52.2. BDB is used by three different packages in this hint; LDAP, Heimdal and nss_db. I have not tried the more recent version of BDB, but I am interested in knowing if it works with all three packages. For installation instructions, see: http://www.linuxfromscratch.org/blfs/view/cvs/content/db.html ------------ NTP-4.2.0 ------------ NTP is not required, though highly recommended. In a Kerberos 5 environment, each machine attempting to authenticate using the KDC server must be within four or five minutes of time syncronization or authentication will fail. A properly configured NTP server on your network can provide time syncronization within a second or two across all machines on the network. For installation instructions, see: http://www.linuxfromscratch.org/blfs/view/cvs/basicnet/ntp.html ------------ cracklib-2.7 ------------ Cracklib is optional. I can't imagine why one would not want to include this package though. It forces the end users to create strong passwords. Using the instructions found at the link below, cracklib will be installed to support both Linux-PAM and the Heimdal Kerberos packages. See: http://www.linuxfromscratch.org/blfs/view/cvs/postlfs/cracklib.html -------------- Linux-PAM-0.77 -------------- Linux-PAM is a mandatory package used for authenticating against the LDAP directory. For installation instructions,see: http://www.linuxfromscratch.org/blfs/view/cvs/postlfs/linux_pam.html ***NOTE*** You should re-install your Shadow package after installing Linux-PAM. It's not required, as we're soon to replace the shadow su and login programs, but it only takes a few minutes and in case you need to back out of your Kerberos installation, the Shadow package will be configured to work with Linux-PAM. For installation instructions, see: http://www.linuxfromscratch.org/blfs/view/cvs/postlfs/shadow.html ------------- Heimdal-0.6.2 ------------- A Kerberos 5 package is mandatory as this is where all the user's passwords are securely stored. I used the Heimdal package. MIT Kerberos 5 should also work, however, I've not tested this. There's a hint for a complete network deployment of Heimdal Kerberos 5 available at: http://www.linuxfromscratch.org/hints/downloads/files/heimdal.txt ---------------- pam_krb5-1.3-rc7 ---------------- The pam_krb5 package is a Linux-PAM module used to authenticate non- kerberized login programs such as xdm, gdm and kdm against the Kerberos and Linux-PAM installation. This package can also be configured to automatically acquire Kerberos TGTs (ticket-granting-tickets). The instructions for installing this package are included in the Heimdal hint. ----------------- Cyrus-SASL-2.1.18 ----------------- Cyrus-SASL is a mandatory package used to provide a secure interface between OpenLDAP and Kerberos. User information is stored in LDAP, user passwords are stored in Kerberos. SASL provides an interface "layer" between the two. You will not need to use the saslauth daemon or create a SASL database. For installation and GSSAPI testing instructions, see the hint at: http://www.linuxfromscratch.org/hints/downloads/files/cyrus-sasl.txt --------------- OpenLDAP-2.1.30 --------------- OpenLDAP is mandatory. For installation instructions, see: http://www.linuxfromscratch.org/blfs/view/cvs/server/openldap.html ***NOTE*** You may want to include --enable-wrappers as an option to the ./configure command if you want LDAP to link against tcpwrappers. ***NOTE*** You'll need to install OpenLDAP on every machine which will be accessing the stored nameservice information in the LDAP and Kerberos databases. You *DO NOT* need to install the slapd or slurpd features of OpenLDAP on machines that will not be used as LDAP servers (master or slave). To install a client-only version of OpenLDAP, without the slapd or slurpd features, use the following switches on the ./configure command: --disable-slapd --disable-slurpd The client-only version will install only the LDAP libraries on the target system. Additionally, you do not need to run the "make test" command during installation of a client-only target. ------------ nss_ldap-217 ------------ The nss_ldap package is really cool. Mandatory, this package builds a library integrating LDAP and Linux-PAM as a native nameservice, allowing you to specify "ldap" in your /etc/nsswitch.conf file. This package is the key to the whole setup. By default, the GNU libc library won't use LDAP/slapd as a nameservice mechanism so we must build the nss_ldap library. Read about PADL's open source software at: http://www.padl.com/Contents/OpenSourceSoftware.html Read about nss_ldap at: http://www.padl.com/OSS/nss_ldap.html Download the package via FTP from: ftp://ftp.padl.com/pub/nss_ldap.tgz Download the package via HTML from: http://www.padl.com/download/nss_ldap.tgz Follow these instructions to build and install the package: ./configure --sysconfdir=/etc make make install ln -sf libnss_ldap-2.3.3.so /lib/libnss_ldap.so ldconfig If desired, strip the debugging symbols from the built library file using the following command: strip --strip-debug /lib/libnss_ldap-2.3.3.so ------------ pam_ldap-169 ------------ The pam_ldap package is mandatory. This package provides the mechanism for Linux systems (with Linux-PAM) to authenticate against LDAP directories. Read about PADL's open source software at: http://www.padl.com/Contents/OpenSourceSoftware.html Read about pam_ldap at: http://www.padl.com/OSS/pam_ldap.html Download the package via FTP from: ftp://ftp.padl.com/pub/pam_ldap.tgz Download the package via HTML from: http://www.padl.com/download/pam_ldap.tgz Follow these instructions to build and install the package: ./configure make make install If desired, strip the debugging symbols from the new PAM module using the following command: strip --strip-debug /lib/security/pam_ldap.so ----------------- MigrationTools-45 ----------------- The MigrationTools-45 package is a bunch of Perl scripts used to migrate nameservice data into an LDAP directory. You'll only need to install this package on the machine used as the master LDAP server (or on another machine where you'll be performing the LDAP data loads from). Read about PADL's open source software at: http://www.padl.com/Contents/OpenSourceSoftware.html Read about MigrationTools at: http://www.padl.com/OSS/MigrationTools.html Download the package via FTP from: ftp://ftp.padl.com/pub/MigrationTools.tgz Download the package via HTML from: http://www.padl.com/download/MigrationTools.tgz There's really no installation required for the MigrationTools package. Simply unpack the tarball where you wish, or unpack and move all the scripts to a desired location. See the README file for additional information. There's also additional configuration information on the PADL MigrationTools web page mentioned previously. ---------- nss_db-2.2 ---------- This package was left for dead by the Glibc maintainers several years ago. It is not required, though highly recommended. The nss_db library makes offline db files of the LDAP Directory available locally. You can configure your NSS lookup to use this facility before going across the network to fetch LDAP user and group information. You may also use nss_db to create db files of other network information such as /etc/services, /etc/rpc and /etc/protocols. Download the nss_db-2.2 package from: http://ftp.gnu.org/gnu/glibc/nss_db-2.2.tar.gz ***NOTE*** The default installation location for the db files is /var/db. There is no mention of this directory in the FHS Guidelines. Therefore, I patched the package to allow for a user-specified db path. You may use the suggested alternate path as shown below or stick with the default /var/db path. The choice is yours. To use /var/db, simply omit the --localstatedir switch to the configure script. Also, you may choose any path you wish. To install the nss_db-2.2 package, follow these instructions: patch -Np1 -i ../nss_db-2.2-update-1.patch (attachment to this hint) aclocal automake -a libtoolize --force autoconf ./configure --prefix=/usr --localstatedir=/var/lib/nss_db make make install If desired, strip the debugging symbols from the installed binaries by using the following commands: strip --strip-all /usr/bin/makedb strip --strip-debug /lib/libnss_db.so.2.0.0 I patched the "make install" target to 1)update the db Makefile with the path you specified in the --localstatedir switch and 2)copy the db Makefile to the specified directory. So, to create the db files, issue the following command: make -f /var/lib/nss_db/Makefile (of course, substitute the correct path) ***NOTE*** This DOES NOT create copies of LDAP information. This command will only duplicate the information in /etc flat files. Later in the hint, when we configure the user/group db files with LDAP information, we'll overwrite the /etc user/group information. -------------- nss_updatedb-1 -------------- The nss_updatedb package is used in conjunction with the pam_ccreds package to provide offline nameservice information. This would be useful in situations when the LDAP directory is unavailable or you wish to use the local db files as the primary lookup service. You'll need to install this package on any machine where you desire this offline capability. Read about PADL's open source software at: http://www.padl.com/Contents/OpenSourceSoftware.html Read about nss_updatedb at: http://www.padl.com/OSS/nss_updatedb.html Download the package via FTP from: ftp://ftp.padl.com/pub/nss_updatedb.tgz Download the package via HTML from: http://www.padl.com/download/nss_updatedb.tgz I patched this package in the same manner as the nss_db-2.2 package. You MUST use the same db file path during installation of this package as you did for the nss_db package. The method is the same, simply pass --localstatedir=/path to the configure script. Omit the switch to use the Glibc default of /var/db. Follow these instructions to install the nss_updatedb package: patch -Np1 -i ../nss_updatedb-1-FHS_compliance-1.patch (hint attachment) autoreconf ./configure --prefix=/usr --localstatedir=/var/lib/nss_db make make install If desired, strip the debugging symbols from the installed binary by using the following command: strip --strip-all /usr/sbin/nss_updatedb ------------ pam_ccreds-1 ------------ The pam_ccreds package is used in conjunction with the nss_updatedb package to provide offline nameservice information. This would be useful in situations when the LDAP directory is unavailable. You'll need to install this package on any machine where you desire this offline capability. Read about PADL's open source software at: http://www.padl.com/Contents/OpenSourceSoftware.html Read about pam_ccreds at: http://www.padl.com/OSS/pam_ccreds.html Download the package via FTP from: ftp://ftp.padl.com/pub/pam_ccreds.tgz Download the package via HTML from: http://www.padl.com/download/pam_ccreds.tgz Follow these instructions to install the pam_ccreds package: Coming Soon! ==================== 3. SSL CERTIFICATES: ==================== ------------ Introduction ------------ In order to access the LDAP server using encrypted methods, you'll need a signed SSL certificate. You can pay a Certificate Authority to provide this, or you can create (and sign) your own. The choice is yours. There's no complications involved using self-signed certificates to access LDAP as there is on web servers. If you have paid a certificate authority to provide you with a signed server certificate and private key, much of this section will be unecessary. Skip to the part titled "Installing the Certificates". A signed certificate for a web server can work, providing the CN or subjectAltName field contains the properly identified host name of the LDAP server. If you have previously created signed SSL certificates for the host being used as the LDAP server, you may use these as well. Skip to the "Installing the Certificates" section. To create and sign your own certificates, you may use the following instructions. ------------------------- Create an RSA Private Key ------------------------- We're going to be creating some files and directories during the process of creating and signing the certificate. Any working directory will be fine. At the end, when we install the certificates, any directory you choose to install them in will be fine. This hint will install the certificates in /etc/openldap/certs. You may create and use this directory now, if you desire. Issue the following command to create a TripleDES encrypted, PEM formatted RSA private key: openssl genrsa -des3 -out server.key 1024 You'll have to enter a "Pass Phrase" when creating the key. This should create a file "server.key" in the current directory. The standard lecture from everything you read about SSL is to backup this file and keep it and the "Pass Phrase" in a secure location. ------------------- Create a Server CSR ------------------- Create a PEM formatted Certificate Signing Request (CSR) using the newly created private key by issuing the following command: openssl req -new -key server.key -out server.csr You'll be prompted for a bunch of stuff. Make sure you enter the LDAP server's Fully Qualified Domain Name when prompted for the "Common Name". To check out the details of the CSR, issue the following command: openssl req -noout -text -in server.csr You now have a choice. Send off to a Certificate Authority and have your certificate signed (usually for a fee), or create your own Certificate Authority and sign your own CSR. If you are going to have your certificate signed by a Certificate Authority, do it then skip to the part below titled "Installing the Certificates". To create your own Certificate Authority, follow the instructions below. ------------------------------ Create a Certificate Authority ------------------------------ First we need to create a TripleDES encrypted, PEM formatted RSA private key for your Certificate Authority. Use the following command: openssl genrsa -des3 -out ca.key 1024 You'll have to enter a "Pass Phrase" when creating the key. This should create a file "ca.key" in the current directory. The standard lecture from everything you read about SSL is to backup this file and keep it and the "Pass Phrase" in a secure location. Next we need to create a PEM formatted, X509 structured self-signed CA certificate using the private key we just created. Use the following command: openssl req -new -x509 -days 730 -key ca.key -out ca.crt Again, you'll be prompted for a bunch of stuff. Make it happy. You may use your name (or whatever you wish) when prompted for the "Common Name". This creates a CA certificate in a file "ca.crt" that is good for 2 years. Adjust the -days parameter in the command above to lengthen/shorten the lifespan. To check out the details of the CA certificate, issue the following command: openssl x509 -noout -text -in ca.crt ------------------- Sign the Server CSR ------------------- This step requires us to use the new CA certificate to "sign" the server CSR we created earlier. This is not easily accomplished using command-line SSL tools. I've provided a script (modified version of the sign.sh script provided by the Apache mod_ssl package) you can use to sign the CSR. The script is an attachment to this hint. First copy the sign.sh script into your working directory and change the permissions to executable. You may want to modify some parameters (default_days sets how long the certificate will be valid for) and the paths if you're not in the /etc/openldap/certs directory. Next, run the script using the following syntax: ./sign.sh server.csr You'll be prompted for the Pass Phrase and to acknowledge signing and committing the certificate. This should create a "server.crt" signed certificate. You can now clean up if you don't need to create any more certificates with the following command: rm -rf ca.db* server.csr ---------------------------- Encrypted or Unencrypted Key ---------------------------- The Private Key (server.key) file you created earlier is encrypted and requires entering the Pass Phrase to use it. When you start the slapd daemon later using the -h command to listen on a secure port, slapd will require access to the key. Thus, you'll have to enter the Pass Phrase at every system boot and every time you restart the slapd daemon. This may be undesirable. One solution is to unencrypt the key and use system permissions to protect access to the key. I mention this now so you'll know what we're talking about later when we set permissions and ownerships of the various configuration files. If you think that using system permissions (only root and the unprivileged ldap user will have access to the key) is better than having to enter the Pass Phrase every time slapd starts, issue the following command to unencrypt the Private Key: mv server.key server.key.encrypted openssl rsa -in server.key.encrypted -out server.key --------------------------- Installing the Certificates --------------------------- We need to install the certificate chain (server.crt, server.key, ca.crt) files somewhere. If you've followed the instructions in this hint, they're currently in /etc/openldap/certs. This is the directory the hint will use for final installation. So, there's really nothing to do except maybe move the Certificate Authority Key file (ca.key) somewhere more secure (removable media, another machine, you choose). If you've sent off for server certificates from a commercial Certificate Authority, the files may have .pem extensions, but they accomplish the same thing. You'll need to install the files into the final directory location. You don't have to use /etc/openldap/certs. You may choose any directory you wish. Just remember what it is so you can update the configuration files with this location later. We'll also lock down the Private Keys with permissions allowing access only to root and the ldap user (we haven't created this user yet). ------------------------------- Final Notes on SSL Certificates ------------------------------- I have not yet created any slave LDAP servers, so I can't document the procedure to set one up. From preliminary reading, it doesn't look difficult. My understanding is that multiple SSL certificates aren't required if the subjectAltName field is used in the certificate. I've not looked into this. So, for the time being, it's kind of up-in-the-air whether you'll need additional SSL certificates for the slave LDAP servers. ========================== 4. SOFTWARE CONFIGURATION: ========================== ------------ Introduction ------------ At this point, all the necessary software should be installed. In particular, insure you have a fully functional Kerberos installation and you were able to successfully run the GSSAPI tests outlined in the Cyrus-SASL hint. Most of the configuration steps deal with OpenLDAP. But first we need to create an unprivileged user and group to run the slapd daemon and own the database and configuration files. ------------------------------ Create the ldap User and Group ------------------------------ Create a new unprivileged user using whatever method you wish. I'm not going to tell you how to do this or what to name the user or what UID and GID to use, you choose. If you cannot do this, you're probably way in over your head anyway. For the purposes of this hint, I've named the user "ldap". The entry in /etc/passwd should look something like the following: ldap:x:20:20:Open-LDAP Owner:/dev/null:/bin/false Create a group for the ldap user. For the purposes of this hint, I've named the group "ldap". The entry in /etc/group should look something like the following: ldap:x:20: ------------------------------------------- Set the Permissions on the SSL Certificates ------------------------------------------- First thing, let's set the proper permissions for the SSL certificates and private keys. We don't want the ldap user to have write access, but must read them. Of course, we must keep all other prying eyes off the keys. Use the following commands to make this happen (if you used a directory other than /etc/openldap/certs, make the appropriate changes): chmod 755 /etc/openldap/certs chown root:ldap /etc/openldap/certs/* chmod 640 /etc/openldap/certs/* chmod 644 /etc/openldap/certs/{server,ca}.crt ---------------------------------------- Create a Kerberos LDAP Service Principal ---------------------------------------- We must create an LDAP service principal and extract it to a keytab file. We don't want to extract it to the main Kerberos keytab file as then the ldap user would need read access to it. This would be undesirable. So, we'll add the principal, then extract it to a new keytab file, readable only by the ldap user. Use these commands (kadmin> designates the kadmin prompt and issue commands at this prompt): kadmin -l kadmin> add --random-key ldap/FQDN_of_LDAP_server kadmin> ext -k /etc/openldap/ldap.keytab ldap/FQDN_of_LDAP_server kadmin> exit (FQDN_of_LDAP_server is the Fully Qualified Domain Name of the LDAP server, which should be the same as the CN field of the SSL server certificate) Now change the ownership and permissions of the ldap.keytab file with the following commands: chown root:ldap /etc/openldap/ldap.keytab chmod 640 /etc/openldap/ldap.keytab ---------------------------------------------------- Setting Permissions and Ownership of Remaining Files ---------------------------------------------------- We're going to set permissions and ownership of the LDAP database and slapd configuration files. But first, make sure your LDAP slapd daemon is not running. If you followed the BLFS book to install Open-LDAP, the daemon may still be running. If you're performing this hint on a machine where LDAP is already being used in a production environment, I trust you'll exercise caution following these steps, and you can make the appropriate changes to the instructions to accomodate your existing installation. Use the following command to stop the slapd daemon: kill -INT `cat /var/lib/slapd.pid` Issue the following command to change the ownership of the LDAP database directory and database files: chown -R ldap:ldap /var/lib/openldap-data My installation of Open-LDAP installed the /var/lib/openldap-data directory with 700 permissions and 600 permissions for the files in the directory. If your installation did not install with these permissions, change them. Next, we need to make the /etc/openldap/slapd.conf file readable by the ldap user. Do this by issuing the following commands: chown root:ldap /etc/openldap/slapd.conf chmod 640 /etc/openldap/slapd.conf ---------------------------------- Configure /etc/openldap/slapd.conf ---------------------------------- First, we need a place for the slapd daemon to create a slapd.pid and slapd.args file. Typically, these files would be created in /var/run, but the ldap user does not have write access to this location. I decided to create these files in /var/run/slapd. I realize this may be unconventional, feel free to to create these files wherever you wish. Here's a workaround that creates the PID files in /var/run: ====================================================================== Create a daemon group and: chgrp daemon /var/run chmod g+w,o+t /var/run This will allow the group daemon to write to /var/run. The o+t insures that each daemon can only delete its own files. Now all you have to do is add daemon users to the group daemon. ====================================================================== Create the PID directory (not required if you chose the workaround): install -o ldap -g ldap -m 755 -d /var/run/slapd You'll need to identify this directory location during the configuring of the slapd.conf file. I can't figure out an easy way to tell you how to configure the slapd.conf file. The easiest thing I came up with is just let you look at a working example file and modify your existing file, or modify the example file and replace your original. The example file is a file with minimum parameters to get you started. You may need/want to expand it with additional parameters to suit your needs and/or environment. Attached to this hint is the example slapd.conf file. You'll need to change the following lines in the file to reflect your domain name (dc fields): saslRegexp uid=([^/]*),cn=GSSAPI,cn=auth uid=$1,ou=people,dc=example,dc=com suffix "dc=example,dc=com" rootdn "cn=Manager,dc=example,dc=com" Additionally, you may need to change the path and filenames of the following: pidfile /var/run/slapd/slapd.pid argsfile /var/run/slapd/slapd.args TLSCertificateFile /etc/openldap/certs/server.crt TLSCertificateKeyFile /etc/openldap/certs/server.key You may also need to change the following to suit your environment: threads 6 idletimeout 14400 cachesize 10000 checkpoint 256 15 ---------------------------------- Configure /etc/openldap/ldap.conf ---------------------------------- The /etc/openldap/ldap.conf file is used by the OpenLDAP utilities (ldapadd, ldapmodify, etc.). I only needed three uncommented lines in the file: URI ldaps://hostname.example.com/ BASE dc=example,dc=com TLS_CACERT /etc/openldap/certs/ca.crt URI should point to the primary LDAP server's FQDN. BASE is the Distinguished Name of your domain. TLS_CACERT is the Certificate Authority certificate you created earlier. ---------------------------------- Configure /etc/ldap.conf ---------------------------------- The /etc/ldap.conf file is used by the nss_ldap library and the LDAP PAM module. This file was installed during the installation of the nss_ldap package. The file is very large and has many, many commented lines, however, I found you only need five uncommented lines: host hostname.example.com base dc=example,dc=com ssl start_tls tls_checkpeer yes tls_cacertfile /etc/openldap/certs/ca.crt The "host" parameter should be set to the FQDN of the LDAP server. The "base" parameter is the Distinguished Name of your domain. The "tls_cacertfile" parameter is the Certificate Authority certificate. ---------------------------------- Configure /etc/nsswitch.conf ---------------------------------- As long as we're configuring files, let's make some adjustments to /etc/nsswitch.conf now. We'll need this during testing after we import a dummy user into LDAP. First we need to add the "ldap" service to the passwd and group lines: passwd: files ldap group: files ldap This tells the Glibc lookup library to first check the local /etc files for the user/group information then consult LDAP if the information wasn't found. Check out the /etc/nsswitch.ldap file installed by the nss_ldap package. This file shows the nameservice lookup capabilites LDAP can provide. ----------------------------------- Configure the LDAP Backend Database ----------------------------------- Simply put, there's too much information on the Internet about this subject for me to try to tell you how to tune your LDAP backend database. In a nutshell, database tuning is accomplished by modifying parameters in the /etc/openldap/slapd.conf file and the database DB_CONFIG file. At a minimum, you should probably experiment with the "set_cachesize" parameter of the DB_CONFIG file. For starters, visit the FAQ page at: http://www.openldap.org/faq/data/cache/893.html You can read the slapd.conf man page for a quick rundown of the available backend database tuning options. Additionally, the OpenLDAP Administrator's Guide at: http://www.openldap.org/doc/admin21/ has some good information. For our initial purposes of this hint, the defaults will be adequate. ------------------------- Client Only Configuration ------------------------- To configure a machine for client only access to the LDAP nameservice, you'll need to copy three files from the LDAP server to the client machine and make the modification to /etc/nsswitch.conf that we did earlier. The three files you need to copy to the client are: /etc/ldap.conf /etc/openldap/ldap.conf /etc/openldap/certs/ca.crt --------------------- Configuration Summary --------------------- Most of the configuration is now complete. We'll make a change to the slapd.conf file a little bit later, we still need to configure PAM and we'll modify the nsswitch.conf file again if you desire to use LDAP for more than just resolving user and group names. But for now, let's move on and create a dummy user to test our current configuration. =========================================== 5. Initial Population of the LDAP Directory =========================================== ---------------- Standard Warning ---------------- As mentioned earlier, if you have an existing production database in the /var/lib/openldap-data directory, make whatever changes are necessary to these instructions to avoid disrupting your production environment. ---------------------- Start the slapd Daemon ---------------------- First, we need to start the slapd daemon. If you followed the BLFS book instructions to install OpenLDAP, you've already started the daemon at least once, thus, a database has already been created. If you desire, wipe out the existing database by removing all files in the /var/lib/openldap-data directory. Careful, if you created a DB_CONFIG file in this directory, don't remove it! We'll start the daemon using the following command: KRB5_KTNAME=/etc/openldap/ldap.keytab \ /usr/sbin/slapd -u ldap -h "ldap:/// ldaps:///" Startup command explanation: KRB5_KTNAME=/etc/openldap/ldap.keytab causes Kerberos to read a different keytab file. -u ldap tells slapd we want the daemon process owned by the ldap user. -h "ldap:/// ldaps:///" tells slapd to listen on both the standard ldap and secure ldap ports. ------------------- Test Access to LDAP ------------------- To cut the monotony of all this configuring, let's test access to LDAP using a quick ldapsearch. This is the same test search used in the BLFS book (performing this test by a user other than root is probably best): ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts If the search fails to return the desired results (see the BLFS book), I can think of three things you may need to check. 1. The slapd daemon failed to start. 2. The SSL Certificate's CN field doesn't match the LDAP server's hostname. 3. Tcpwrappers is misconfigured. -------------------- Import the LDIF File -------------------- There are several methods one can use to populate an LDAP directory. Before we begin, please read the information on this page: http://www.openldap.org/doc/admin21/dbtools.html This will acquaint you with what we're about to do, as well as showing you additional attribute values you can use in the LDIF file. I'll go get coffee while you read the documentation. :-) Okay, now we're ready. A sample LDIF file (dummy.ldif) is included as an attachment to this hint. You'll need to modify it to suit your desires and environment. You may change the user name to anything you wish, however, you should choose a name that's not in /etc/passwd, NIS or any other nameservice mechanism you may be using. After you've modified the sample file to your liking, import it using the following command: ldapadd -f dummy.ldif -x -D "cn=Manager,dc=example,dc=com" -W Command explanation: -f dummy.ldif specifies the file to import -x specifies using simple authentication instead of SASL -D "blah,blah,blah" tells ldapadd to bind to LDAP using Distinguished Name "blah,blah,blah" (insure you modified the dc fields) -W specifies to prompt for simple authentication instead of providing the password on the command line. The password is indentified in your slapd.conf file as the attribute to the "rootpw" parameter. If the import was successful, five lines of: adding new entry "blah, blah" were displayed. We'll be testing the new user's ability to access the system a little later, so you'll probably want to create the user's home directory and populate it. ============================ 6. TESTING THE INSTALLATION: ============================ ---------------- Using ldapsearch ---------------- We'll be testing access to LDAP six different ways using the "ldapsearch" command. We'll test using simple authentication and SASL authentication with three different access methods for each. Here's a quick rundown of the command line parameters we'll use (man ldapsearch for a complete discussion): -b searchbase - Uses searchbase as the starting point for the search. -H ldapuri - Use ldapuri as the URI referring to the LDAP server (we'll use it to access both the standard and secure LDAP ports). -x - Use simple authentication instead of SASL. -ZZ - Use StartTLS operation and require the operation to be successful. For each test, you'll need to modify the FQDN and dc fields. Issue the command for the first test (simple authentication, no encryption): ldapsearch -b dc=example,dc=com -H ldap://FQDN/ -x As with all the ldapsearch tests we'll do here, this should return the entire contents of the Directory as we specified no filter. Examine the results and make sure the data is what you expected. If the data doesn't look correct, it means you didn't configure the LDIF file quite right. The next step is instructions to remove/modify the data you just entered so you can recreate/modify the dummy user's Directory attributes. Skip this step and move on to "Resuming the ldapsearch Tests" if you are satisfied with the data in the Directory and don't wish to replace/modify the data. ---------------------------------- Modifying Entries in the Directory ---------------------------------- First of all, I wouldn't worry too much about anything we do here. If you believe the database will become fragmented, or you might screw something up, ease your mind. At worse case, you simply shut down the slapd daemon, remove all the database files from the LDAP data directory, restart the daemon and import your LDIF file again. However, to gain confidence using the LDAP commands, let's play with one of them. Let's use the "ldapmodify" command. Keep in mind the ldapadd command is actually a hard link to the ldapmodify command. Let's say you erred on the dummy users' UID number and need to change it. First of all, I'm not sure the "ldapmodify" command is really meant to be used interactively as it's fairly cumbersome. Almost all the reference material I found (including the man page) shows using the command with the "-f file" argument (use an LDIF file instead of stdin). Additionally, I haven't found a way to terminate standard input except for Control-D. Nevertheless, you can use the command interactively without creating an LDIF input file like this: ldapmodify -D "cn=Manager,dc=example,dc=com" -W -x (You'll be prompted for the password, then a blank prompt awaiting input) dn: uid=dummy1,ou=people,dc=example,dc=com uidNumber: 1006 (enter two blank lines and the following will be displayed:) modifying entry "uid=dummy1,ou=people,dc=example,dc=com" At this point, the only thing I can figure out to do is Control-D to exit and return to the shell prompt. A cleaner method is to use an input LDIF file and use the command like this: ldapmodify -D "cn=Manager,dc=example,dc=com" -W -x -f changes.ldif Try it if you want. First, use the following to create the LDIF file: cat > changes.ldif << "EOF" dn: uid=dummy1,ou=people,dc=example,dc=com uidNumber: 1007 - EOF If you wish, use the ldapsearch command we used earlier to confirm the changes to the dummy users' UID. Lastly, the ldapadd, ldapmodify and ldapdelete commands all have very similar syntax. Reference the man pages for a full discussion. A little later on, we're going to comment out the "rootpw" parameter in slapd.conf. This will require a slight change (for the better) in the usage of the commands as you will request slapd to bind using SASL authentication via LDAP ACL's. After slapd.conf is changed and the daemon is restarted, you'll use the commands as follows: ldapmodify -f changes.ldif (or just ldapmodify if you want interactive use) ----------------------------- Resuming the ldapsearch Tests ----------------------------- We'll run through these tests to check all the access methods. Make the appropriate changes to the FQDN and dc fields. You'll need to acquire a Kerberos TGT before starting the SASL authentication tests. The output from the SASL authentication tests will confirm SASL/GSSAPI access. Simple authentication on the LDAP SSL port: ldapsearch -b dc=example,dc=com -H ldaps://FQDN/ -x Simple authentication using SSL via StartTLS: ldapsearch -b dc=example,dc=com -H ldap://FQDN/ -ZZ -x SASL authentication without encryption: ldapsearch -b dc=example,dc=com -H ldap://FQDN/ SASL authentication on the LDAP SSL port: ldapsearch -b dc=example,dc=com -H ldaps://FQDN/ SASL authentication using SSL via StartTLS ldapsearch -b dc=example,dc=com -H ldap://FQDN/ -ZZ If you received unexpected results, or error messages, I don't have a lot to offer in the way of help. My first attempt at this setup was successful, and I really never had to perform any troubleshooting. There's some good tips on troubleshooting available at: http://www.ofb.net/~jheiss/krbldap/howto.html If all the tests dumped the contents of the Directory, you're well on your way. It's downhill from here. There's really nothing left to do except add whatever else you want in the Directory and perform a couple more configuration steps. So, let's move on with some other tests. ------------------ Using System Tests ------------------ Use the "id" command to verify the existance of the dummy user we created: id dummy1 This should return uid, gid and groups in numerical and alpha display. Next use the following command to get the "passwd" entry for the dummy user: getent passwd dummy1 This should display a line identical to one found in an /etc/passwd file. Isn't that cool? ------------------------------ Logging in With the Dummy User ------------------------------ As mentioned before, you should probably create and populate the dummy user's home directory before trying to log in as that user. This means you need to create the home directory on each machine the dummy user will log into. If /home is NFS mounted on these machines, this is a bonus as you won't have to create directories all over the place. Additionally, you need to add a Kerberos user principle for the dummy user. Now it's time to play around with some configured client systems and use the dummy user. Use su, telnet, rlogin, ftp or whatever access method you wish to test out the user, using as many machines as possible (I realize more than one is redundant). Login at a console, telnet to another machine, ftp a file or two. Whatever. Just play around 'til you're confident with the setup. **NOTE** xdm, gdm, kdm or other display manager logins are not yet set up in PAM, so you won't be able to use an X display manager login. ========================= 7. CONFIGURING LINUX-PAM: ========================= If you've been using PAM, and are familiar with it, you can probably just add the pam_ldap.so and pam_krb5.so modules into your existing configuration and run with it. Some examples for using the two modules can be found in the pam.d directory of the pam_ldap and pam_krb5 source trees. I can't imagine not following these examples. I say this because they wrote the modules, their instructions for using them should be better than anything I can tell you. Additionally, the README files in both source trees have good stuff. If you have not been using Linux-PAM in your environment until you started in on this hint, I suggest you research PAM on your own before beginning this section. A tutorial for fully configuring PAM is beyond the scope of this hint. Hopefully, I can get you started. You chose a method of configuring PAM during the initial installation. Either you chose to create an /etc/pam.conf file or you created an /etc/pam.d directory. Both methods provide the same functionality. I found the pam.d directory a better choice for me. If you followed the instructions for configuring PAM in the PAM and Shadow BLFS packages, you have a solid start. You'll need to add the modules mentioned in the first paragraph into your configuration file(s). Follow the examples given in the package source trees to configure the four module types (auth, account, session and password) and the control-flag keywords (required, requisite, sufficient and optional). You may have to vary from the examples due to your environment requirements. I have not yet experimented with the newer control-flag syntax of Linux-PAM. Check out the page at: http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam-4.html for a full explanation of all the available configuration options. ============================================ 8. COMPLETING THE LDAP DIRECTORY POPULATION: ============================================ This section is forthcoming. ========================================== 9. ISSUES, GOTCHAS AND OTHER SUNDRY ITEMS: ========================================== 1) Stopping the slapd deamon by any other means than "kill -INT pid" can cause problems. The LDAP Administrator's Guide says this: "Killing slapd by a more drastic method may cause information loss or database corruption." Believe it. During development on a server without UPS protection, I lost power to the machine. Things restarted normally, but accessing the data in the database would cause one of the slapd thread processes to gobble 100% CPU and never return the result. I checked everything. Finally, as a last stopgap measure, I recreated the LDAP backend database and re-imported the data. Everything was fine after that. Two things should be learned from this. One, kill the daemon properly, and two, perform and keep reliable backups of the LDAP backend database. ========= 10. TODO: ========= 1) Document the procedures for creating and propogating slave LDAP servers. 2) Document the procedures for putting the Kerberos database inside LDAP. 3) Add MIT Kerberos commands alongside Heimdal commands to accommodate MIT. ============ 11. CLOSING: ============ This section is forthcoming. ACKNOWLEDGEMENTS: Jason Heiss for the information on his web site at: http://www.ofb.net/~jheiss/krbldap/howto.html Luke Howard for a fix to an nss_db db-open bug DJ Lucas for the research and assistance with nss_db CHANGELOG: [2004.05.16] * Original draft (some sections incomplete)