|Linux System Administration|
OpenLDAP client on Debian lenny
Not only is OpenLDAP a useful tool in which to store information, such as the names, phone numbers and addresses of everyone in an organization, but it can also be used to store Unix account information. Not only that, but it can store passwords as well, which means that it can be used for authentication as well as authorization.
This article builds on a previous one in which an OpenLDAP provider server was set up, called ldaps1.example.com, containing a user account (ccolumbus) with a matching password (NewWorld). The goal is to set up a client machine that is capable of using this LDAP account for both authentication and authorization, as well as creating a new home directory for it on the first successful login attempt.
A word of warning, however. Although this is an interesting and educational exercise, as a solution it does not include any encryption whatsoever. In other words, login names, passwords and adata are sent over the network as clear text, which means that it cannot in any way be considered secure.
In this example, client software for OpenLDAP is installed on a host running Debian 5.0 (lenny). If followed properly, the step-by-step process should produce a new client machine.
Before the actual OpenLDAP installation process can begin, it will first be necessary to install Debian lenny on a new host called ldapc1.example.com. A DNS server must also be available on the network with a zone file to which forward and reverse mappings can be added for this host. After the initial installation of the operating system, make sure these packages are installed on the system as well:
~# apt-get install ssh nmap
Now the installation process for the OpenLDAP client can begin:
1. OpenLDAP client install
On the new host, ldapc1.example.com, run the following command to test if the previously installed OpenLDAP server is actually available on the network:
~# nmap ldaps1.example.com
This should be among the results:
PORT STATE SERVICE 389/tcp open ldap
If there is a problem, fix this first. If not, continue by installing these four packages:
~# apt-get install ldap-utils libnss-ldap libpam-ldap nscd
As a result, five packages are installed, including one dependency:
ldap-utils 2.4.11-1 OpenLDAP utilities libnss-ldap 261-2.1 NSS module for using LDAP as a naming service libpam-ldap 184-4.2 Pluggable Authentication Module for LDAP libsasl2-modules 2.1.22.dfsg1-23+lenny1 Cyrus SASL - pluggable authentication modules nscd 2.7-18 GNU C Library: Name Service Cache Daemon
During the installation procedure, certain questions will be asked about two of these packages, first, about libnss-ldap. Answer them as follows:
LDAP server Uniform Resource Identifier: ldap://ldaps1.example.com/ Distinguished name of the search base: dc=example,dc=com LDAP version to use: 3 LDAP account for root: cn=manager,dc=example,dc=net LDAP root account password:
To be sure, the third question is left at its default and no password is given for the fourth, because in this case an LDAP account for the root user is unncessary. These four questions are immediately followed by two more regarding libpam-ldap. Answer them as follows:
Make local root database admin: No Does the LDAP database require login?: No
Since the debconf configuration of libnss-ldap can be improved upon if performed a second time, use this command to reconfigure it:
~# dpkg-reconfigure libnss-ldap
The questions are a little different the second time around. Answer them as follows:
LDAP server Uniform Resource Identifier: ldap://ldaps1.example.com/ Distinguished name of the search base: dc=example,dc=com LDAP version to use: 3 Does the LDAP database require login? No Special LDAP privileges for root? No Make the configuration file readable/writeable by its owner only? No
NB: Regarding the question of which LDAP server to use, this field supports mutiple server URIs (URLs), which can be filled in here, just like in the next step.
The three packages − nscd, libnss-ldap and libpam-ldap − not only make it possible for users with accounts that exist only in LDAP to log into hosts that they have never before logged into, but also help all users − including those with Unix-only accounts − to resolve the UID and GID numbers of files owned by users with LDAP accounts.
In scenarios unlike this one, where the OpenLDAP server does not allow anonymous queries, libnss-ldap will require an LDAP account with which authenticate and search the DIT independently. And since nscd, for which libnss-ldap is a module, runs as root, that is why an LDAP account is requested for root; it does not mean that an account is required with administrative access to the DIT!
Edit /etc/ldap/ldap.conf and use these two lines:
BASE dc=example,dc=com URI ldap://ldaps1.example.com/
This configuration file is used to set system-wide defaults for LDAP clients.
As is mentioned during the install procedure for libnss-ldap, the /etc/nsswitch.conf configuration file needs to be edited before authentication and authorization via LDAP can work. These are the necessary changes that must be made to it:
passwd: compat ldap group: compat ldap shadow: compat ldap
However, there is an irritating bug in this version of libnss_ldap that manifests itself during the boot process. It causes the host to attempt to contact the LDAP server before the local network interface has been activated, which results in something like a minute's worth of errors about libnss_ldap not being able to contact the LDAP server − very tedious indeed.
There are at least two solutions to this problem. The first is simple: it still leads to a series of errors during the boot process, but they pass much more quickly. The second is a bit more involved, but prevents any errors from occurring at all. First, the simple solution. Basically, all that is necessary is to edit /etc/libnss-ldap.conf and add this single line:
#bind_policy hard bind_policy soft
Then, restart the Name Service Cache Daemon:
~# /etc/init.d/nscd restart
If this solution is employed, skip the rest and move on to step 4.
The second solution to this problem is suggested in a Debian bug report and involves maintaining two extra copies of /etc/nsswitch.conf: one version that includes support for LDAP and one that does not. The LDAP version is used to overwrite the original just after the network interface is activated, while the non-LDAP version is used to overwrite the original just before the interface is deactivated. To implement this workaround, first create the two copies of the existing /etc/nsswitch.conf:
~# cp /etc/nsswitch.conf /etc/nsswitch.conf.org ~# cp /etc/nsswitch.conf /etc/nsswitch.conf.ldap
Assuming that the earlier described changes to /etc/nsswitch.conf have already been made, edit one of its copies, /etc/nsswitch.conf.org, and remove "ldap" again from the same three lines, thereby returning it to the original state of its parent:
passwd: compat group: compat shadow: compat
Create two scripts that will overwrite the active version of nsswitch.conf.ldap with the LDAP-enabled version or the original. The first one is called /usr/local/bin/nsswitch-org and has the following contents:
#!/bin/sh /bin/cp /etc/nsswitch.conf.org /etc/nsswitch.conf exit 0
The second script, /usr/local/bin/nsswitch-ldap, is just a little different:
#!/bin/sh /bin/cp /etc/nsswitch.conf.ldap /etc/nsswitch.conf exit 0
Do not forget to make these two new scripts executable:
~# chmod 750 /usr/local/bin/nsswitch-*
Now add two lines to /etc/network/interfaces, for post-up and pre-down, to run these scripts after the interface is activated and before it is deactivated. In this example, the interface is eth0 and uses DHCP:
iface eth0 inet dhcp post-up /usr/local/bin/nsswitch-ldap pre-down /usr/local/bin/nsswitch-org
This is only a workaround and is not perfect. In particular, if the host is shut down improperly so that the /usr/local/bin/nsswitch-ldap script has not had a chance to execute, the aforementioned irritating errors will occur during the next bootup. This cannot be helped, because the problem with libnss_ldap occurs before the root file system is mounted read/write, making it impossible to implement any solution at that stage of the process.
At this point there are various ways to get this script-swapping process going, but the easiest is probably just to reboot:
This way, no LDAP errors will occur when the system starts up again and afterwards the configuration of the host can continue.
4. PAM configuration
Altering the client machine's Linux-PAM configuration will make it possible for users to authenticate using either a Unix or an LDAP account. However, as PAM is both a relatively complex subject and a recurring theme, it was decided to create a dedicated page for it. Those unfamiliar with its workings are advised to read it. Otherwise, make the modifications described below, which are followed by a few explanations.
Edit /etc/pam.d/common-auth and change it to:
auth sufficient pam_unix.so nullok_secure auth sufficient pam_ldap.so use_first_pass auth required pam_deny.so
Edit /etc/pam.d/common-account and change it to:
account sufficient pam_unix.so account sufficient pam_ldap.so account required pam_deny.so
Edit /etc/pam.d/common-password and change it to:
password sufficient pam_unix.so nullok obscure md5 password sufficient pam_ldap.so password required pam_deny.so
Edit /etc/pam.d/common-session and change it to:
session required pam_unix.so session required pam_mkhomedir.so session optional pam_ldap.so
In this modified PAM configuration, three new modules are introduced:
In /etc/pam.d/common-auth, an argument is used for the pam_ldap.so module: use_first_pass. This forces it to use a password that was used for the previous module in the stack so that it does not prompt the user. The module will fail only if the password is absent or invalid.
Using sufficient instead of required for pam_ldap.so and pam_unix.so in the first three of these configuration files creates a situation where success is possible if only one of the two modules succeeds. However, it also means that the stack is no longer capable of producing a return status to indicate failure. To remedy this, the pam_deny.so module is added with required to the end of the stack to ensure that the entire process will still return a failure in case neither of the previous modules returns a success.
At this point it should be possible to authenticate to the new client using the LDAP account created previously on the server (ccolumbus, password: NewWorld). If all goes well, a matching home directory will be created automatically upon login and, despite a lack of any related Unix account information in /etc/passwd or /etc/group, the UID and GID of the new home directory will be resolved to the new account name anyway, thanks to LDAP. These LDAP-created UIDs and GIDs will be resolved for all users of this host, including the ones that only have local Unix accounts, provided the LDAP server remains available.
6. See also
7. Further reading