This guide will walk you through setting up Debian Stretch to use an LDAP directory server for authentication. I am assuming you have a directory server up and running. If you don’t, you can follow these two guides to install and configure OpenLDAP:
Install Packages
First, you need to install and configure a LDAP pluggable authentication module (PAM), a LDAP name service switch (NSS) module, and a caching service. I prefer nss-pam-ldapd because it is available in the OS repositories and straightforward to configure. It is what the examples in this guide will use. Install the necessary packages by running the following command:
apt install libnss-ldapd nslcd libpam-ldapd openssl nscd
You will be prompted to enter some information. Make sure nothing is selected; I will be walking you through each configuration step.
TLS CA Certificates
I recommend using TLS for your connections to your directory server(s). If you don’t, user names and passwords will be sent through the network unencrypted. If you opt to not use TLS, then skip this section. If your directory server certificate was obtained from one of the well known certificate authorities, you can probably use your system’s trusted certificate authority (CA) certificate list. On Debian Stretch, this is /etc/ssl/certs/ca-certificates.crt. If you are using a self-signed certificate or an in-house certificate authority, you will need to get a copy of the certificate used to sign the directory server(s) server certificates.
Well Known CA
If your directory server is using a certificate issued by one of the well known CAs, then you are done with this section. Read the comment regarding tls_cacertfile in the example nlscd.conf file.
Local CA
Contact your CA administrator and ask them for the CA certificate in PEM format. I keep CA certificates that don’t ship with the OS in/pki/cacerts.pem. Append the CA certificate to this file, or if you like, a location of your choosing.
Self-Signed Certificate
Create a directory to store your certificate files in and obtain the certificates from your directory server. I recommend keeping self-signed certificates in a separate file. If possible, ask your directory server administrator for the certificates in PEM format. If this isn’t possible, it can be obtained with OpenSSL. Run the following openssl command on the directory servers, if possible. If you run it on the clients, you are susceptible to a man in the middle attack.
openssl s_client -connect ldap.tylersguides.com:636 -showcerts < /dev/null
From the output of the openssl command, copy and paste the certificate text into /pki/ldap_server_certs.pem or a location of your choosing. Do this for each server. The certificate text will look something like this:
-----BEGIN CERTIFICATE-----
MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv
MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
pu/xO28QOG8=
-----END CERTIFICATE-----
Nss-pam-ldapd uses the same file,/etc/nslcd.conf, for the NSS and PAM modules. I have included an example file with comments explaining what the various options do. There are many more options than the ones in the example. It wouldn’t hurt to skim through the official documentation to see what options are available. Replace the highlighted values in the example below with what is relevant to your system.
# The user and group name the cache daemon will run as.
uid nslcd
gid nslcd
# Make sure to use the fully qualified domain name or the TLS handshake
# will fail and you won't be able to connect.
# The URI if your directory server(s). Multiple servers can be specified.
uri ldaps://ldap.tylersguides.com/
# uri ldaps://ldap2.tylersguides.com
# This should be your suffix.
base dc=tylersguides,dc=com
# The LDAP user the cache daemon and modules will use for looking
# up entries
binddn cn=osproxy,ou=system,dc=tylersguides,dc=com
# The password for the aforementioned account
bindpw osproxy_password
# Where to look for groups and users, respectively.
base group ou=groups,dc=tylersguides,dc=com
base passwd ou=users,dc=tylersguides,dc=com
# How long, in seconds, to wait for the server to respond when logging in
# as the aforementioned user before giving up
bind_timelimit 30
# How long to wait for the server when searching for entries.
timelimit 30
# TLS configuration. tls_reqcert demand will prevent the daemon and modules
# using the server if the server certificate does not have a signing chain
# that ends with a root certificate listed in the file set by tls_cacertfile
ssl on
tls_reqcert demand
# If your directory server uses a certificate from a well known CA,
# comment out the next line and uncomment the one below it.
tls_cacertfile /pki/cacerts.pem
#tls_cacertfile /etc/ssl/certs/ca-bundle.crt
tls_ciphers SECURE256
You may want or need to adjust the tls_ciphers. The Debian nss-pam-ldapd package uses GnuTLS. See the GnuTLS documentation for guidance on specifying ciphers. Now enable and restart nslcd.
Nss-pam-ldapd uses a daemon to lookup directory entries. Set nslcd to automatically start on boot and restart it.
systemctl enable nslcd
systemctl restart nslcd
Enable and Test NSS
Before you enable and test your configuration, backup /etc/nsswitch.conf and /etc/pam.d
cp /etc/nsswitch.conf /etc/nsswitch.conf.pre_ldap
cp -Rp /etc/pam.d /etc/pam.d/pre_ldap
Create a home directory for your test user. If you used my guide on configuring the server, the commands below will work as is. Otherwise, change the UID, GID, and user name to match an entry on your directory server.
mkdir /home/testuser
chown 5000:5000 /home/testuser
Once you have everything configured, there are two things you need to do to enable it: set your name service switch to use ldap and add the PAM module to your PAM configuration. Make a copy of /etc/nsswitch.conf and then add the word ldap to the passwd, group, and shadow lines like in the example below.
passwd: compat ldap
group: compat ldap
shadow: compat ldap
Restart nscd1 and ensure it is set to start when the system boots:
systemctl restart nscd
systemctl enable nscd
Now test the configuration by trying to resolve UIDs and GIDs.
ls -l /home
Working configuration:
root@ldap:~# ls -l /home
total 8
drwxr-xr-x 2 testuser testgroup 4096 Jul 24 16:03 testuser
drwxr-xr-x 2 tyler tyler 4096 May 22 2016 tyler
Broken configuration:
root@ldap:~# ls -l /home
total 8
drwxr-xr-x 2 5000 5000 4096 Jul 24 16:03 testuser
drwxr-xr-x 2 tyler tyler 4096 May 22 2016 tyler
If your ls command shows /home is owned by your test user and group instead of the numeric UID and GID, your configuration is working. If it isn’t working, try restarting nslcd. Then I would check /var/log/messages and /var/log/syslog for clues. You could also try running nslcd in debug mode. The following command will do this. Press Ctrl+C to stop nslcd when you are finished:
systemctl stop nslcd
nslcd -d
Some potential causes:
- The client and server(s) fail to negotiate a cipher suite. Adjust tls_ciphers in nslcd.conf
- The certificate authority certificate that signed the server certs is not in your tls_cacertfile. Obtain the necessary certificates and add them to your file.
- The TLS certificate subject does not match the hostname of the server. Make sure you use fully qualified domain names (FQDN)s in your uri lines. You may need to add /etc/hosts entries if you cannot resolve the FQDNs via DNS.
- You are suppling incorrect credentials on your binddn and bindpw lines.
- Your search base lines don’t match your directory servers.
- Nslcd can’t read the CA certificates file.
Configure PAM
First, backup your PAM directory. If you make a mistake or run into unexpected problems, it may leave the system in a state where you are not able to login at all.
cp -Rp /etc/pam.d /etc/pam.d.pre_ldap
Run the following command to enable LDAP authentication:
pam-auth-update
Make sure the boxes next to “LDAP Authentication”, “UNIX authentication”, and “Register user sessions in the systemd control group hierarchy” are checked.
Test LDAP Authentication
Try logging in with your testuser:
ssh -l testuser
Notes
- The name service cache daemon (nscd) caches resolver requests. I.e., it prevents excessive name service lookups. When the data source is on a remote server, such as an OpenLDAP server, caching the lookups can drastically improve name resolution performance. For example, if you were to list a directory’s contents with
ls -l
, the resolver would only have to reach out to the directory server the first time it encounters a new UID or GID rather than once for every file in the directory.