Difference between revisions of "LDAP authentication"

From ArchWiki
Jump to: navigation, search
(use https for links to archlinux.org)
m (Introduction and Concepts)
(35 intermediate revisions by 9 users not shown)
Line 1: Line 1:
 +
[[Category:Networking]]
 
[[Category:Security]]
 
[[Category:Security]]
{{Merge|OpenLDAP Authentication}}
+
{{Related articles start}}
{{Poor writing}}
+
{{Related|OpenLDAP}}
 +
{{Related|LDAP Hosts}}
 +
{{Related articles end}}
  
== HOWTO - LDAP Authentication in Arch Linux ==
+
== Introduction and Concepts ==
  
=== Overview ===
+
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).
  
What you need to install, configure, and know, to get LDAP RFC 2251 Authentication working on Arch.
+
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.
  
Steps:
+
=== NSS and PAM ===
 +
NSS (which stands for Name Service Switch) is a system mechanism to configure different sources for common configuration databases. For example, {{ic|/etc/passwd}} is a {{ic|file}} type source for the {{ic|passwd}} database.
  
# Install OpenLDAP
+
PAM (which stands for Pluggable Authentication Module) is a mechanism used by Linux (and most *nixes) to extend its authentication schemes based on different plugins.
# Design LDAP Directory
 
# Configure and Fill OpenLDAP
 
# Configure NSS
 
# Configure PAM
 
  
==== References ====
+
So to summarize, we need to configure NSS to use the OpenLDAP server as a source for the {{ic|passwd}}, {{ic|shadow}} and other configuration databases and then configure PAM to use these sources to authenticate it's users.
  
http://aqua.subnet.at/~max/ldap/
+
== LDAP Server Setup ==
  
==== For the newbies ====
+
=== Installation ===
  
If you are totally new to those concepts, here is an good introduction that is easy to understand and that will get you started, even if you are new to everything LDAP.
+
You can read about installation and basic configuration in the [[OpenLDAP]] article. After you have completed that, return here.
  
http://www.brennan.id.au/20-Shared_Address_Book_LDAP.html
+
=== Set up access controls ===
  
=== Install OpenLDAP ===
+
To make sure that no-one can read the (encrypted) passwords from the LDAP server, but a user can edit their own password, add the following to {{ic|/etc/openldap/slapd.conf}} and restart {{ic|slapd.service}} afterwards:
See the [[OpenLDAP]] article
 
  
=== Design LDAP Directory ===
+
{{hc|slapd.conf|2=
 +
access to attrs=userPassword
 +
        by self write
 +
        by anonymous auth
 +
        by * none
  
This all depends on what organization your network/computer is modeling.
+
access to *
 +
        by self write
 +
        by * read
 +
}}
  
Here is my initial layout in LDIF Format<pre>
+
=== Populate LDAP Tree with Base Data ===
dn: dc=tklogic,dc=net
+
 
dc: tklogic
+
Create a file called {{ic|base.ldif}} with the following text:
description: The techknowlogic.net Network
+
 
 +
{{hc|base.ldif|<nowiki>
 +
# example.org
 +
dn: dc=example,dc=org
 +
dc: example
 +
o: Example Organization
 
objectClass: dcObject
 
objectClass: dcObject
 
objectClass: organization
 
objectClass: organization
o: techknowlogic.net
 
  
dn: ou=People,dc=tklogic,dc=net
+
# 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
 
ou: People
 +
objectClass: top
 
objectClass: organizationalUnit
 
objectClass: organizationalUnit
  
dn: ou=Groups, dc=tklogic,dc=net
+
# Groups, example.org
 +
dn: ou=Groups,dc=example,dc=org
 
ou: Groups
 
ou: Groups
 
objectClass: top
 
objectClass: top
 
objectClass: organizationalUnit
 
objectClass: organizationalUnit
 +
</nowiki>}}
  
dn: cn=tklusers,ou=Groups,dc=tklogic,dc=net
+
Add it to your OpenLDAP Tree:
gidNumber: 2000
 
objectClass: posixGroup
 
objectClass: top
 
cn: tklusers
 
  
dn: ou=Roles,dc=tklogic,dc=net
+
$ ldapadd -D "cn=Manager,dc=example,dc=org" -W -f base.ldif
ou: Roles
 
description: Org Unit for holding a basic set of ACL Roles.
 
objectClass: top
 
objectClass: organizationalUnit
 
  
dn: cn=ldap-reader,ou=Roles,dc=tklogic,dc=net
+
Test to make sure the data was imported:
userPassword: {CRYPT}xxxxxxxxxxxxx
 
objectClass: organizationalRole
 
objectClass: simpleSecurityObject
 
cn: ldap-reader
 
description: LDAP reader user for any unrestricted reads (i.e. for NSS)
 
  
dn: cn=ldap-manager,ou=Roles,dc=tklogic,dc=net
+
$ ldapsearch -x -b 'dc=example,dc=org' '(objectclass=*)'
userPassword: {CRYPT}xxxxxxxxxxxxx
 
objectClass: organizationalRole
 
objectClass: simpleSecurityObject
 
cn: ldap-manager
 
description: LDAP manager user for any unrestricted read/writes (i.e. root-like)
 
</pre>
 
  
Now for each user: <pre>
+
=== Adding users ===
dn: uid=user,ou=People,dc=tklogic,dc=net
+
To manually add a user, create an {{ic|.ldif}} file like this:
 +
{{hc|example.ldif|<nowiki>
 +
dn: uid=johndoe,ou=People,dc=example,dc=org
 
objectClass: top
 
objectClass: top
 
objectClass: person
 
objectClass: person
Line 86: Line 91:
 
objectClass: posixAccount
 
objectClass: posixAccount
 
objectClass: shadowAccount
 
objectClass: shadowAccount
uid: user
+
uid: johndoe
cn: Test User
+
cn: John Doe
sn: User
+
sn: Doe
givenName: Test
+
givenName: John
 
title: Guinea Pig
 
title: Guinea Pig
 
telephoneNumber: +0 000 000 0000
 
telephoneNumber: +0 000 000 0000
Line 95: Line 100:
 
postalAddress: AddressLine1$AddressLine2$AddressLine3
 
postalAddress: AddressLine1$AddressLine2$AddressLine3
 
userPassword: {CRYPT}xxxxxxxxxx
 
userPassword: {CRYPT}xxxxxxxxxx
labeledURI: http://test.tklogic.net/
+
labeledURI: https://archlinux.org/
 
loginShell: /bin/bash
 
loginShell: /bin/bash
uidNumber: 10000
+
uidNumber: 9999
gidNumber: 2000
+
gidNumber: 9999
homeDirectory: /users/test/
+
homeDirectory: /home/johndoe/
description: A Test User for the ArchWiki LDAP-Authentication HOWTO
+
description: This is an example user
</pre>
+
</nowiki>}}
  
=== Configure and Fill OpenLDAP ===
+
the {{ic|xxxxxxxxxx}} in the {{ic|userPassword}} entry should be replaced with the value in {{ic|/etc/shadow}} or use the {{ic|slappasswd}} command.
  
'''Client Side'''
+
You can automatically migrate all of your local accounts (and groups, etc.) to the LDAP directory using PADL Software's [http://www.padl.com/OSS/MigrationTools.html Migration Tools].
  
''/etc/openldap/ldap.conf''
+
== Client Setup ==
BASE    dc=yourdomain,dc=com
 
URI    ldap://yourdomain.com
 
  
''/etc/pam_ldap.conf and /etc/nss_ldap.conf''
+
Install the OpenLDAP client as described in [[OpenLDAP]]. Make sure you can query the server with {{ic|ldapsearch}}.
  
If there is an actual difference between these files, please let me know.  
+
Next, [[pacman|install]] {{AUR|nss-pam-ldapd}} from the [[official repositories]].
  
>> There's not. In Gentoo we use only one /etc/ldap.conf file, so I made hardlinks on these two, using only one file it works. Wonder why Arch has it separated. Anybody knows?
+
=== NSS Configuration ===
 +
NSS is a system facility which manages different sources as configuration databases. For example, {{ic|/etc/passwd}} is a {{ic|file}} type source for the {{ic|passwd}} database, which stores the user accounts.
  
>>> Actually I have moved the /etc/nss_ldap.conf to /etc/ldap.conf. /etc/openldap/ldap.conf and /etc/nss_ldap.conf are only sym-links to /etc/ldap.conf. Works fine for me.
+
Edit {{ic|/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 {{ic|ldap}} directive to the {{ic|passwd}}, {{ic|group}} and {{ic|shadow}} databases, so be sure your file looks like this:
  
  host yourdomain.com
+
  passwd: files ldap
  base dc=yourdomain,dc=com
+
  group: files ldap
  uri ldap://yourdomain.com/
+
  shadow: files ldap
ldap_version 3
 
rootbinddn cn=Manager,dc=yourdomain,dc=com
 
scope sub
 
timelimit 5
 
bind_timelimit 5
 
nss_reconnect_tries 2
 
pam_login_attribute uid
 
pam_member_attribute gid
 
pam_password md5
 
pam_password exop
 
nss_base_passwd ou=People,dc=yourdomain,dc=com
 
nss_base_shadow ou=People,dc=yourdomain,dc=com
 
 
 
''/etc/ldap.secret''
 
plaintextpassword
 
 
 
Chmod to 600
 
 
 
 
 
'''Server Side'''
 
  
''/etc/openldap/slapd.conf''
+
Edit {{ic|/etc/nslcd.conf}} and change the {{ic|base}} and {{ic|uri}} lines to fit your ldap server setup.
include        /etc/openldap/schema/core.schema
 
include        /etc/openldap/schema/cosine.schema
 
include        /etc/openldap/schema/inetorgperson.schema
 
include        /etc/openldap/schema/nis.schema
 
include        /etc/openldap/schema/courier.schema
 
allow bind_v2
 
password-hash {md5}
 
pidfile  /var/run/slapd.pid
 
argsfile  /var/run/slapd.args
 
database        bdb
 
suffix          "dc=yourdomain,dc=com"
 
rootdn          "cn=Manager,dc=yourdomain,dc=com"
 
rootpw          password (Use slappasswd -h {MD5} -s passwordstring)
 
directory      /var/lib/openldap/openldap-data
 
index  objectClass    eq
 
index  uid    eq
 
  
=== Configure NSS ===
+
Start {{ic|nslcd.service}} using systemd.
  
'' /etc/nsswitch.conf''
+
You now should see your LDAP users when running {{ic|getent passwd}} on the client.
passwd:        files
 
group:          files
 
hosts:          dns
 
services:  files
 
networks:  files
 
protocols:  files
 
rpc:        files
 
ethers:    files
 
netmasks:  files
 
bootparams: files
 
publickey:  files
 
automount:  files
 
aliases:    files
 
sendmailvars:  files
 
netgroup:  file
 
  
''/etc/nsswitch.ldap''
+
==== Name Service Cache Daemon ====
passwd:        files ldap
+
You can optionally run NSCD. This is a daemon that NSS uses to cache lookups and queries for network backends. This way you can login when the LDAP server is down, it will also reduce load on the LDAP server.
group:          files ldap
 
hosts:          dns ldap
 
services:  ldap [NOTFOUND=return] files
 
networks:  ldap [NOTFOUND=return] files
 
protocols:  ldap [NOTFOUND=return] files
 
rpc:        ldap [NOTFOUND=return] files
 
ethers:    ldap [NOTFOUND=return] files
 
netmasks:  files
 
bootparams: files
 
publickey:  files
 
automount:  files
 
sendmailvars:  files
 
netgroup:  ldap [NOTFOUND=return] files
 
  
 +
Start {{ic|nscd.service}} using systemd.
  
''/etc/rc.sysinit''
+
{{Note|It is recommended to stop the NSCD when troubleshooting because it may mask problems by serving cached queries.}}
  
'''Be sure to modify this file before you reboot or your machine will hang on "Starting UDev Daemon"'''
+
=== PAM Configuration ===
 +
The basic rule of thumb for PAM configuration is to include {{ic|pam_ldap.so}} wherever {{ic|pam_unix.so}} is included. Arch moving to {{pkg|pambase}} has helped decrease the amount of edits required. For more details about configuring pam, the [https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Managing_Smart_Cards/PAM_Configuration_Files.html RedHat Documentation] is quite good. You might also want the upstream documentation for [http://arthurdejong.org/nss-pam-ldapd nss-pam-ldapd].
  
Add this before UDev starts
+
{{Tip|If you want to prevent UID clashes with local users on your system, you might want to include {{ic|minimum_uid&#61;10000}} or similar on the end of the {{ic|pam_ldap.so}} lines. You'll have to make sure the LDAP server returns uidNumber fields that match the restriction.}}
cp /etc/nsswitch.file /etc/nsswitch.conf
 
  
And this after UDev is started
+
{{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 {{ic|pam_ldap.so}} lines, don't change the relative order of the other lines without good reason! Simply insert LDAP within the chain.}}
cp /etc/nsswitch.ldap /etc/nsswitch.conf
 
  
Hopefully there will be a fix later.
+
First edit {{ic|/etc/pam.d/system-auth}}. This file is included in most of the other files in {{ic|pam.d}}, so changes here propagate nicely. Updates to {{pkg|pambase}} may change this file.
  
udev / ldap boot update ->
+
Make {{ic|pam_ldap.so}} sufficient at the top of each section, except in the ''session'' section, where we make it optional.
please see: https://wiki.archlinux.org/index.php/Udev-ldap_workaround
+
{{hc|/etc/pam.d/system-auth|
</pre>
+
'''auth      sufficient pam_ldap.so'''
 +
auth      required  pam_unix.so    try_first_pass nullok
 +
auth      optional  pam_permit.so
 +
auth      required  pam_env.so
  
'''Alternative Fix'''
+
'''account  sufficient pam_ldap.so'''
 +
account  required  pam_unix.so
 +
account  optional  pam_permit.so
 +
account  required  pam_time.so
  
If you do not require LDAP to discover your host is to have the nsswitch.conf read
+
'''password  sufficient pam_ldap.so'''
  hosts:          files dns
+
password required  pam_unix.so    try_first_pass nullok sha512 shadow
this will bypass the need to modify ''/etc/rc.sysinit'' and not hang on boot
+
password  optional  pam_permit.so
  
=== Configure PAM ===
+
session  required  pam_limits.so
 +
session  required  pam_unix.so
 +
'''session  optional  pam_ldap.so'''
 +
session  optional  pam_permit.so
 +
}}
  
This is what my files look like. It may not be exactly right, but it works on my systems.
+
Then edit both {{ic|/etc/pam.d/su}} and {{ic|/etc/pam.d/su-l}} identically. The {{ic|su-l}} file is used when the user runs {{ic|su --login}}.
  
''/etc/pam.d/login''
+
Make {{ic|pam_ldap.so}} sufficient at the top of each section, and add {{ic|use_first_pass}} to {{ic|pam_unix}} in the ''auth'' section.
auth            requisite      pam_securetty.so
+
{{hc|/etc/pam.d/su|
auth           requisite      pam_nologin.so
+
#%PAM-1.0
auth           sufficient     pam_ldap.so
+
'''auth     sufficient    pam_ldap.so'''
auth            required        pam_unix.so use_first_pass
+
auth     sufficient   pam_rootok.so
auth           required        pam_tally.so onerr=succeed file=/var/log/faillog
+
# Uncomment the following line to implicitly trust users in the "wheel" group.
account        required        pam_access.so
+
#auth     sufficient    pam_wheel.so trust use_uid
account        required       pam_time.so
+
# Uncomment the following line to require a user to be in the "wheel" group.
account        required       pam_unix.so
+
#auth    required     pam_wheel.so use_uid
account         sufficient     pam_ldap.so  
+
auth      required pam_unix.so '''use_first_pass'''
password        sufficient      pam_ldap.so
+
'''account   sufficient   pam_ldap.so'''
session        required       pam_mkhomedir.so skel=/etc/skel/ umask=0022
+
account  required pam_unix.so
session        required        pam_unix.so
+
'''session   sufficient    pam_ldap.so'''
session         required        pam_env.so
+
session   required pam_unix.so
session         required       pam_motd.so
+
}}
session        required        pam_limits.so
 
session        optional        pam_mail.so dir=/var/spool/mail standard
 
session        sufficient      pam_ldap.so
 
session        optional        pam_lastlog.so
 
  
''/etc/pam.d/shadow''
+
To enable users to edit their password, edit {{ic|/etc/pam.d/passwd}}:
auth            sufficient      pam_rootok.so
 
auth            required        pam_unix.so
 
auth            sufficient      pam_ldap.so use_first_pass
 
account        required        pam_unix.so
 
account        sufficient      pam_ldap.so
 
session        required        pam_unix.so
 
session        sufficient      pam_ldap.so
 
password        sufficient      pam_ldap.so
 
password        required        pam_permit.so
 
  
''/etc/pam.d/passwd''
+
{{hc|/etc/pam.d/passwd|2=
password        sufficient      pam_ldap.so  
+
#%PAM-1.0
password        required        pam_unix.so shadow nullok
+
'''password        sufficient      pam_ldap.so'''
 +
#password      required        pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3
 +
#password      required        pam_unix.so sha512 shadow use_authtok
 +
password        required        pam_unix.so sha512 shadow nullok
 +
}}
  
''/etc/pam.d/su''
+
==== Create home folders at login ====
auth            sufficient      pam_rootok.so
 
auth            sufficient      pam_ldap.so
 
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
 
  
Note: pam_rootok.so must come before pam_ldap.so, otherwise startup scripts like '/etc/rc.d/postgres' ask for a password
+
If you want home folders to be created at login (eg: if you aren't using NFS to store home folders), edit {{ic|/etc/pam.d/system-login}} and add {{ic|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, kdm, gdm, etc. You might choose to edit additional files in the same way, such as {{ic|/etc/pam.d/su}} and {{ic|/etc/pam.d/su-l}} to enable it for {{ic|su}} and {{ic|su --login}}. If you don't want to do this for ssh logins, edit {{ic|system-local-login}} instead of {{ic|system-login}}, etc.
  
''/etc/pam.d/sudo''
+
{{hc|/etc/pam.d/system-login|
auth           sufficient      pam_ldap.so
+
...top of file not shown...
auth            required       pam_unix.so use_first_pass
+
session    optional  pam_loginuid.so
auth            required       pam_nologin.so
+
session    include    system-auth
 +
session    optional  pam_motd.so         motd&#61;/etc/motd
 +
session    optional  pam_mail.so          dir&#61;/var/spool/mail standard quiet
 +
-session  optional  pam_systemd.so
 +
session    required   pam_env.so
 +
'''session    required   pam_mkhomedir.so skel&#61;/etc/skel umask&#61;0022'''
 +
}}
  
''/etc/pam.d/sshd''
+
{{hc|/etc/pam.d/su-l|
auth            required        pam_nologin.so
+
...top of file not shown...
auth            sufficient      pam_ldap.so
+
'''session        required        pam_mkhomedir.so skel&#61;/etc/skel umask&#61;0022'''
auth            required        pam_env.so
+
session        sufficient      pam_ldap.so
auth            required        pam_unix.so use_first_pass
+
session        required        pam_unix.so
account        sufficient      pam_ldap.so
+
}}
account        required        pam_unix.so
 
account        required        pam_time.so
 
password        required        pam_ldap.so
 
password        required        pam_unix.so
 
session        required        pam_mkhomedir.so skel=/etc/skel/ umask=0022
 
session        required        pam_unix_session.so
 
session        sufficient      pam_ldap.so  
 
session        required        pam_limits.so
 
  
=== Troubleshooting ===
+
==== Enable sudo ====
  
After migrating to LDAP or updating an LDAP-backed system udevd can hang at boot at the message "Starting UDev Daemon". This is usually caused by udevd trying to look up a name from LDAP but failing, because the network is not up yet. The solution is to ensure that all system group names are present locally.
+
To enable sudo from an LDAP user, edit {{ic|/etc/pam.d/sudo}}. You'll also need to modify sudoers accordingly.
 +
{{hc|/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
 +
}}
  
Extract the group names referenced in udev rules and the group names actually present on the system:
+
== Resources ==
 +
[http://arthurdejong.org/nss-pam-ldapd/setup The official page of the nss-pam-ldapd packet]
  
# fgrep -r GROUP /etc/udev/rules.d/ /lib/udev/rules.d | perl -nle '/GROUP\s*=\s*"(.*?)"/ && print $1;' | sort | uniq > udev_groups
+
The PAM and NSS page at the Debian Wiki [http://wiki.debian.org/LDAP/NSS 1] [http://wiki.debian.org/LDAP/PAM 2]
# cut -f1 -d: /etc/gshadow /etc/group | sort | uniq > present_groups
 
  
To see the differences, do a side-by-side diff:
+
[http://www.fatofthelan.com/articles/articles.php?pid=24 Using LDAP for single authentication]
  
# diff -y present_groups udev_groups
+
[http://www.cs.dixie.edu/ldap/ Heterogeneous Network Authentication Introduction]
...
 
network       <
 
nobody       <
 
ntp       <
 
optical optical
 
power       | pcscd
 
rfkill       <
 
root root
 
scanner scanner
 
smmsp       <
 
storage storage
 
...
 
  
In this case, the pcscd group is for some reason not present in the system. Add the missing groups:
+
[http://readlist.com/lists/suse.com/suse-linux-e/36/182642.html Discussion on suse's mailing lists about nss-pam-ldapd]
 
 
# groupadd pcscd
 
 
 
Also, make sure local resources are looked up before resorting to LDAP. {{ic|/etc/nsswitch.conf}} should contain the line
 
 
 
group: files ldap
 

Revision as of 09:05, 14 December 2013

Introduction and Concepts

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.

NSS and PAM

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 Module) 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 it's users.

LDAP Server Setup

Installation

You can read about installation and basic configuration in the OpenLDAP article. 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 a user can edit their own password, add the following to /etc/openldap/slapd.conf and restart slapd.service afterwards:

slapd.conf
access to attrs=userPassword
        by self write
        by anonymous auth
        by * none

access to *
        by self write
        by * read

Populate LDAP Tree with Base Data

Create a 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=Groups,dc=example,dc=org
ou: Groups
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:

example.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.

You can automatically migrate all of your local accounts (and groups, etc.) to the LDAP directory using PADL Software's Migration Tools.

Client Setup

Install the OpenLDAP client as described in OpenLDAP. Make sure you can query the server with ldapsearch.

Next, install nss-pam-ldapdAUR from the official repositories.

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.

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.

Start nslcd.service using systemd.

You now should see your LDAP users when running getent passwd on the client.

Name Service Cache Daemon

You can optionally run NSCD. This is a daemon that NSS uses to cache lookups and queries for network backends. This way you can login when the LDAP server is down, it will also reduce load on the LDAP server.

Start nscd.service using systemd.

Note: It is recommended to stop the NSCD when troubleshooting because it may mask problems by serving cached queries.

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 RedHat 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'll 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, don't 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.

/etc/pam.d/system-auth
auth      sufficient pam_ldap.so
auth      required  pam_unix.so     try_first_pass nullok
auth      optional  pam_permit.so
auth      required  pam_env.so

account   sufficient pam_ldap.so
account   required  pam_unix.so
account   optional  pam_permit.so
account   required  pam_time.so

password  sufficient pam_ldap.so
password  required  pam_unix.so     try_first_pass nullok sha512 shadow
password  optional  pam_permit.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, and add use_first_pass to pam_unix in the auth section.

/etc/pam.d/su
#%PAM-1.0
auth      sufficient    pam_ldap.so
auth      sufficient    pam_rootok.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_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3
#password       required        pam_unix.so sha512 shadow use_authtok
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 aren't 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, kdm, 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 don't 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=0022
/etc/pam.d/su-l
...top of file not shown...
session         required        pam_mkhomedir.so skel=/etc/skel umask=0022
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'll 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

Resources

The official page of the nss-pam-ldapd packet

The PAM and NSS page at the Debian Wiki 1 2

Using LDAP for single authentication

Heterogeneous Network Authentication Introduction

Discussion on suse's mailing lists about nss-pam-ldapd