LDAP authentication

Related articles
OpenLDAP
LDAP Hosts
Identity management
This is a guide on how to configure an Arch Linux installation to authenticate against an LDAP directory. This LDAP directory can be either local (installed on the same computer) or network (e.g. in a lab environment where central authentication is desired).
The guide is divided into two parts. The first part deals with how to setup an
OpenLDAP
server that hosts the authentication directory. The second part deals with how to setup the NSS and PAM modules that are required for the authentication scheme to work on the client computers. If you just want to configure Arch to authenticate against an already existing LDAP server, you can skip to the
second part
.
Terminology
NSS (which stands for Name Service Switch) is a system mechanism to configure different sources for common configuration databases. For example,
/etc/passwd
is a
file
type source for the
passwd
database.
PAM
(which stands for Pluggable Authentication Modules) is a mechanism used by Linux (and most *nixes) to extend its authentication schemes based on different plugins.
So to summarize, we need to configure NSS to use the OpenLDAP server as a source for the
passwd
,
shadow
and other configuration databases and then configure PAM to use these sources to authenticate its users.
LDAP server setup
Installation
Install the OpenLDAP server
and configure the
server
and
client
. After you have completed that, return here.
Set up access controls
To make sure that no-one can read the (encrypted) passwords from the LDAP server, but still allowing users to edit some of their own select attributes (such as own password and photo), create the temporary LDIF
allowpwchange.ldif
Note
Alter the domain components "example" and "org" to your needs
allowpwchange.ldif
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to attrs=cn,givenName,sn,userPassword,shadowLastChange,mail,loginShell,photo by self write by anonymous auth by dn.base="cn=Manager,dc=example,dc=org" write by * none
olcAccess: {1}to * by self read by dn.base="cn=Manager,dc=example,dc=org" write by * read
Import it on database number 0 (cn=config):
$ slapmodify -n 0 -l allowpwchange.ldif
Then
restart
slapd.service
afterwards.
Populate LDAP tree with base data
Create a temporary file called
base.ldif
with the following text.
base.ldif
# example.org
dn: dc=example,dc=org
dc: example
o: Example Organization
objectClass: dcObject
objectClass: organization

# Manager, example.org
dn: cn=Manager,dc=example,dc=org
cn: Manager
description: LDAP administrator
objectClass: organizationalRole
objectClass: top
roleOccupant: dc=example,dc=org

# People, example.org
dn: ou=People,dc=example,dc=org
ou: People
objectClass: top
objectClass: organizationalUnit

# Groups, example.org
dn: ou=Group,dc=example,dc=org
ou: Group
objectClass: top
objectClass: organizationalUnit
Add it to your OpenLDAP tree:
$ ldapadd -D "cn=Manager,dc=example,dc=org" -W -f base.ldif
Test to make sure the data was imported:
$ ldapsearch -x -b 'dc=example,dc=org' '(objectclass=*)'
Adding users
To manually add a user, create an
.ldif
file like this:
user_joe.ldif
dn: uid=johndoe,ou=People,dc=example,dc=org
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: johndoe
cn: John Doe
sn: Doe
givenName: John
title: Guinea Pig
telephoneNumber: +0 000 000 0000
mobile: +0 000 000 0000
postalAddress: AddressLine1$AddressLine2$AddressLine3
userPassword: {CRYPT}xxxxxxxxxx
labeledURI: https://archlinux.org/
loginShell: /bin/bash
uidNumber: 9999
gidNumber: 9999
homeDirectory: /home/johndoe/
description: This is an example user
The
xxxxxxxxxx
in the
userPassword
entry should be replaced with the value in
/etc/shadow
or use the
slappasswd
command. Now add the user:
$ ldapadd -D "cn=Manager,dc=example,dc=org" -W -f user_joe.ldif
You can add a group similarly with
group_joe.ldif
dn: cn=joe,ou=Group,dc=example,dc=org
objectClass: top
objectClass: posixGroup
cn: joe
gidNumber: 9999
Note
You can automatically migrate all of your local accounts (and groups, etc.) to the LDAP directory using PADL Software's
openldap-migrationtools
AUR
.
Client setup
Install the OpenLDAP client as described in
OpenLDAP
. Make sure you can query the server with
ldapsearch
.
Depending on your target, choose either
online-only
or
online and offline
authentication.
Online authentication
NSS configuration
NSS is a system facility which manages different sources as configuration databases. For example,
/etc/passwd
is a
file
type source for the
passwd
database, which stores the user accounts.
Install
the
nss-pam-ldapd
package.
Edit
/etc/nsswitch.conf
which is the central configuration file for NSS. It tells NSS which sources to use for which system databases. We need to add the
ldap
directive to the
passwd
,
group
and
shadow
databases, so be sure your file looks like this:
passwd: files ldap
group: files ldap
shadow: files ldap
Edit
/etc/nslcd.conf
and change the
base
and
uri
lines to fit your ldap server setup.
Edit the
binddn
and the
bindpw
if your LDAP server requires a password. Make sure you change the permission of your
/etc/nslcd.conf
to
0600
for
nslcd
to start properly.
Start
nslcd.service
using systemd.
You now should see your LDAP users when running
getent passwd
on the client.
PAM configuration
The basic rule of thumb for PAM configuration is to include
pam_ldap.so
wherever
pam_unix.so
is included. Arch moving to
pambase
has helped decrease the amount of edits required. For more details about configuring pam, the
Red Hat Documentation
is quite good. You might also want the upstream documentation for
nss-pam-ldapd
.
Tip
If you want to prevent UID clashes with local users on your system, you might want to include
minimum_uid=10000
or similar on the end of the
pam_ldap.so
lines. You will have to make sure the LDAP server returns uidNumber fields that match the restriction.
Note
Each facility (auth, session, password, account) forms a separate chain and the order matters. Sufficient lines will sometimes "short circuit" and skip the rest of the section, so the rule of thumb for
auth
,
password
, and
account
is
sufficient
lines before
required
, but after required lines for the
session
section;
optional
can almost always go at the end. When adding your
pam_ldap.so
lines, do not change the relative order of the other lines without good reason! Simply insert LDAP within the chain.
First edit
/etc/pam.d/system-auth
. This file is included in most of the other files in
pam.d
, so changes here propagate nicely. Updates to
pambase
may change this file.
Make
pam_ldap.so
sufficient at the top of each section, except in the
session
section, where we make it optional. Note the incremented numbers in the
pam_systemd_home.so
lines too. Refer to
pam.conf(5)
if in doubt.
/etc/pam.d/system-auth
auth       required                    pam_faillock.so      preauth
# Optionally use requisite above if you do not want to prompt for the password
# on locked accounts.
-auth      [success=
3
default=ignore]  pam_systemd_home.so
auth       [success=2 default=ignore]  pam_ldap.so
auth       [success=1 default=bad]     pam_unix.so          try_first_pass nullok
auth       [default=die]               pam_faillock.so      authfail
auth       optional                    pam_permit.so
auth       required                    pam_env.so
auth       required                    pam_faillock.so      authsucc
# If you drop the above call to pam_faillock.so the lock will be done also
# on non-consecutive authentication failures.

-account   [success=
2
default=ignore]  pam_systemd_home.so
account    [success=1 default=ignore]  pam_ldap.so
account    required                    pam_unix.so
account    optional                    pam_permit.so
account    required                    pam_time.so

-password  [success=
2
default=ignore]  pam_systemd_home.so
password   [success=1 default=ignore]  pam_ldap.so
password   required                    pam_unix.so          try_first_pass nullok shadow
password   optional                    pam_permit.so

-session   optional                    pam_systemd_home.so
session    required                    pam_limits.so
session    required                    pam_unix.so
session    optional                    pam_ldap.so
session    optional                    pam_permit.so
Then edit both
/etc/pam.d/su
and
/etc/pam.d/su-l
identically. The
su-l
file is used when the user runs
su --login
.
Make
pam_ldap.so
sufficient at the top of each section but below
pam_rootok
, and add
use_first_pass
to
pam_unix
in the
auth
section.
/etc/pam.d/su
#%PAM-1.0
auth      sufficient    pam_rootok.so
auth      sufficient    pam_ldap.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth     sufficient    pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group.
#auth     required      pam_wheel.so use_uid
auth      required	pam_unix.so
use_first_pass
account   sufficient    pam_ldap.so
account   required	pam_unix.so
session   sufficient    pam_ldap.so
session   required	pam_unix.so
To enable users to edit their password, edit
/etc/pam.d/passwd
:
/etc/pam.d/passwd
#%PAM-1.0
password        sufficient      pam_ldap.so
password        required        pam_unix.so sha512 shadow nullok
Create home folders at login
If you want home folders to be created at login (eg: if you are not using NFS to store home folders), edit
/etc/pam.d/system-login
and add
pam_mkhomedir.so
to the
session
section above any "sufficient" items. This will cause home folder creation when logging in at a tty, from ssh, xdm, sddm, gdm, etc. You might choose to edit additional files in the same way, such as
/etc/pam.d/su
and
/etc/pam.d/su-l
to enable it for
su
and
su --login
. If you do not want to do this for ssh logins, edit
system-local-login
instead of
system-login
, etc.
/etc/pam.d/system-login
...top of file not shown...
session    optional   pam_loginuid.so
session    include    system-auth
session    optional   pam_motd.so          motd=/etc/motd
session    optional   pam_mail.so          dir=/var/spool/mail standard quiet
-session   optional   pam_systemd.so
session    required   pam_env.so
session    required   pam_mkhomedir.so skel=/etc/skel umask=0077
/etc/pam.d/su-l
...top of file not shown...
session         required        pam_mkhomedir.so skel=/etc/skel umask=0077
session         sufficient      pam_ldap.so
session         required        pam_unix.so
Enable sudo
To enable sudo from an LDAP user, edit
/etc/pam.d/sudo
. You will also need to modify sudoers accordingly.
/etc/pam.d/sudo
#%PAM-1.0
auth      sufficient    pam_ldap.so
auth      required      pam_unix.so
try_first_pass
auth      required      pam_nologin.so
You will also need to add in
/etc/openldap/ldap.conf
the following:
/etc/openldap/ldap.conf
sudoers_base ou=sudoers,dc=example,dc=org
Online and offline authentication with SSSD
See
SSSD
for an overview and installation.
Note
You must configure
StartTLS
for your LDAP server, or SSSD will not work
SSSD configuration
If it does not exist create
/etc/sssd/sssd.conf
.
/etc/sssd/sssd.conf
[sssd]
config_file_version = 2
services = nss, pam
domains = LDAP

[domain/LDAP]
cache_credentials = true
enumerate = true

id_provider = ldap
auth_provider = ldap

ldap_uri = ldap://server1.example.org, ldap://server2.example.org
ldap_search_base = dc=example,dc=org
ldap_id_use_start_tls = true
ldap_tls_reqcert = demand
ldap_tls_cacert = /etc/openldap/certs/cacerts.pem
chpass_provider = ldap
ldap_chpass_uri = ldap://server1.example.org
entry_cache_timeout = 600
ldap_network_timeout = 2

# OpenLDAP supports posixGroup, uncomment the following two lines
# to get group membership support (and comment the other conflicting parameters)
#ldap_schema = rfc2307
#ldap_group_member = memberUid

# Other LDAP servers may support this instead
ldap_schema = rfc2307bis
ldap_group_member = uniqueMember
The above is an example only. See
sssd.conf(5)
for the full details.
Finally set the file permissions
chmod 600 /etc/sssd/sssd.conf
otherwise SSSD will fail to start.
NSCD configuration
This article or section is out of date.
Reason:
nscd
was removed in
glibc 2.38-4
. (Discuss in
Talk:LDAP authentication
)
Disable caching for passwd, group and netgroup entries in
/etc/nscd.conf
as it will interfere with sssd caching.
Keep caching enabled for hosts entries otherwise some services may fail to start.
/etc/nscd.conf
# Begin /etc/nscd.conf
[...]
enable-cache		passwd
no
[...]
enable-cache		group
no
[...]
enable-cache		hosts		yes
[...]
enable-cache		netgroup
no
[...]
# End /etc/nscd.conf
NSS configuration
Edit
/etc/nsswitch.conf
as follows:
/etc/nsswitch.conf
# Begin /etc/nsswitch.conf

passwd: files
sss
group: files
sss
shadow: files
sss
sudoers: files sss
publickey: files

hosts: files dns myhostname
networks: files

protocols: files
services: files
ethers: files
rpc: files

netgroup: files

# End /etc/nsswitch.conf
PAM configuration
The first step is to edit
/etc/pam.d/system-auth
as follows:
/etc/pam.d/system-auth
#%PAM-1.0
auth sufficient pam_sss.so forward_pass
auth required pam_unix.so try_first_pass nullok
auth optional pam_permit.so
auth required pam_env.so
account [default=bad success=ok user_unknown=ignore authinfo_unavail=ignore] pam_sss.so
account required pam_unix.so
account optional pam_permit.so
account required pam_time.so
password sufficient pam_sss.so
password required pam_unix.so try_first_pass nullok sha512 shadow
password optional pam_permit.so
session     required      pam_mkhomedir.so skel=/etc/skel/ umask=0077
session required pam_limits.so
session required pam_unix.so
session optional pam_sss.so
session optional pam_permit.so
Note
If you happen to use
GNOME/Keyring
: adding 'sufficient' in the beginning of the PAM stack results in Gnome Keyring not being unlocked. For a solution, look at
Advanced PAM Configuration
.
These PAM changes will apply to fresh login. To also allow the
su
command to authenticate through SSSD, edit
/etc/pam.d/su
:
/etc/pam.d/su
#%PAM-1.0
auth            sufficient        pam_rootok.so
auth sufficient   pam_sss.so      forward_pass
auth            required        pam_unix.so
account [default=bad success=ok user_unknown=ignore authinfo_unavail=ignore] pam_sss.so
account         required        pam_unix.so

session         required        pam_unix.so
session optional pam_sss.so
Enable sudo
Edit
/etc/pam.d/sudo
as follows:
/etc/pam.d/sudo
#%PAM-1.0
auth           sufficient      pam_sss.so
auth           required        pam_unix.so try_first_pass
auth           required        pam_nologin.so
Also add sudo service to the list of enabled services and the search base in
/etc/sssd/sssd.conf
:
/etc/sssd/sssd.conf
[sssd]
...
services = nss, pam,
sudo
...

[domain/LDAP]
...
ldap_sudo_search_base = ou=sudoers,dc=example,dc=org
...
Alternately,
configure sudo
to allow the desired LDAP users to use
sudo
.
Password management
For changing expired passwords when logging in using
su
add a password entry to
/etc/pam.d/su
if it is missing:
/etc/pam.d/su
#%PAM-1.0

[...]

auth        include     system-auth
account     include     system-auth
session     include     system-auth
password    include     system-auth
Start/enable
sssd.service
.
You should now be able to see details of your ldap users with
getent passwd
username
or
id
username
.
Once you have logged in with a user the credentials will be cached and you will be able to login using the cached credentials when the ldap server is offline or unavailable.
See also
The official page of the nss-pam-ldapd packet
Debian Wiki - LDAP/NSS
Debian Wiki - LDAP/PAM
Using LDAP for single authentication
Heterogeneous Network Authentication Introduction
Discussion on suse's mailing lists about nss-pam-ldapd
Fedora's SSSD User Guide