LDAP¶
LDAP is a VM running on NFS (ID 101) and connects directly to USTCnet.
Server¶
We use OpenLDAP server (slapd
)
Setup¶
On a freshly installed Debian server, install slapd
with all recommended packages.
The first time slapd asks for an admin password, enter anything you like (we'll change it later).
After apt
completes, run dpkg-reconfigure slapd
to re-configure the LDAP server. This time pay attention to each prompt.
- First prompt is domain name, used to generate the base Distinguished Name (DN). Enter
acsa
to create a short base DNdc=acsa
. - Second prompt is organization, just enter
acsa
. It's not known what this is used for. - Then enter the admin password and repeat it. All changes to the LDAP database will require this password in the future.
- Last prompt is whether to move the old database. Answer Yes here to avoid them cluttering up the server. It's safe to clear
/var/backups
after this.
Make sure the server service is enabled and running. Check systemctl status slapd.service
.
Create directory for users and groups¶
Create 00-basic.ldif
with the following content:
dn: ou=user,dc=acsa
objectClass: organizationalUnit
ou: user
dn: ou=group,dc=acsa
objectClass: organizationalUnit
ou: group
Import the above definitions into LDAP database:
ldapadd -x -D "cn=admin,dc=acsa" -W -f 00-basic.ldif
Enter the admin password when prompted.
Now create a "user group" under the group
directory:
dn: cn=acsastaff,ou=group,dc=acsa
objectClass: posixGroup
cn: acsastaff
gidNumber: 2000
description: ACSA staff
Save to 01-group.ldif
and import it with a similar command as above.
SSL Certificate¶
To allow the server to be reached with different hostnames (e.g. DNS and plain IP), we created a self-signed certificate with the following Subject Alternative Names:
DNS: ldap
DNS: ldap.acsalab.com
IP: <server IPv4>
IP: <server IPv6>
XCA is an easier way to generate (and manage) your certificates than operating the openssl
command.
Copy the certificate file (in PEM text format) and the private key file (also in PEM text format) onto the server. Place them under /etc/ldap
and change file mode to 0644 (certificate) and 0400 (private key).
Use the following LDIF file to configure the server:
dn: cn=config
changetype: modify
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/server.key
dn: cn=config
changetype: modify
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/server.crt
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ldap/server.crt
Order is important
It's not documented, but the private key must be added before the certificate. Otherwise you'll get this response:
ldap_modify: Other (e.g., implementation specific) error (80)
Open /etc/default/slapd
, find SLAPD_SERVICES
and add ldaps:///
to the list. It's recommended to remove ldap://
to disable unencrypted connections.
Restart the server (systemctl restart slapd.service
) for the changes to take effect.
ACL¶
By default, only the admin user can modify the "database" where user data is stored. Only the local root user can modify server settings (the tree under DN cn=config
). Everyone else has read-only access to the database, including unauthenticated clients.
- When using the admin user, specify
-D cn=admin,dc=acsa -W
to use password authentication. - When using local root user, run the
ldap*
commands as root and use-Y EXTERNAL
to use "external authentication".
-Y EXTERNAL
authentication method
The "external" authentication method defers authentication to the transport layer. There are (at least) two kinds of supported methods: Unix domain socket SO_PEERCRED
(see unix(7)
) and TLS client certificate. When connecting over UDS, the server knows the client's UID, GID and PID.
To list existing access control policies, use ldapsearch
:
ldapsearch -Y EXTERNAL -b cn=config olcAccess
To make maintenance easier, we allow the local root user to also modify the database (in addition to server settings).
Configuration process
ldapsearch -Y EXTERNAL -b 'olcDatabase={1}mdb,cn=config' olcAccess
This yields the following result:
# {1}mdb, config
dn: olcDatabase={1}mdb,cn=config
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read
Also note how the root user is identified:
dn: olcDatabase={-1}frontend,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
So to allow the root user to modify the database, we need to insert a rule at top:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
-
add: olcAccess
olcAccess: to attrs=userPassword by self write by anonymous auth by * none
-
add: olcAccess
olcAccess: to attrs=shadowLastChange by self write by * read
-
add: olcAccess
olcAccess: to * by self write by * read
Samba support¶
Install slapd-contrib
package so the Samba module is available on disk.
Add the module to load list:
dn: cn=modules{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: {1}smbk5pwd.la
Restart slapd
, then add the module config:
dn: olcOverlay={0}smbk5pwd,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSmbK5PwdConfig
olcOverlay: {0}smbk5pwd
olcSmbK5PwdEnable: samba
olcSmbK5PwdMustChange: 0
To enable Samba access for a user, add the following attribute:
dn: uid=ibug,ou=user,dc=acsa
changetype: modify
add: objectClass
objectClass: sambaSamAccount
-
add: sambaSID
sambaSID: S-1-5-21-0000000000-0000000000-0000000000-2001
The last group of digits should match the user's uidNumber
.
The user must change their password once for the module to populate sambaNTPassword
and sambaLMPassword
attributes. The password need not be different.
Web UI¶
To ease management, we use wheelybird/ldap-user-manager as the web UI. We deploy this as a Docker container on the LDAP VM.
#!/bin/sh
NAME=lum
docker rm -f "$NAME"
docker run -itd \
--name="$NAME" \
--restart=always \
--net=host \
--add-host=ldap.acsalab.com:127.0.0.1 \
-v /etc/ldap/server.crt:/run/ldap/server.crt:ro \
-v /etc/ldap/server.key:/opt/ssl/server.key:ro \
-v /etc/ldap/server.crt:/opt/ssl/server.crt:ro \
-v /root/.config/ldap:/run/secrets/ldap:ro \
-e SERVER_HOSTNAME=ldap.acsalab.com \
-e SERVER_KEY_FILENAME=server.key \
-e SERVER_CERT_FILENAME=server.crt \
-e CA_CERT_FILENAME=server.crt \
-e ORGANISATION_NAME="ACSA Lab" \
-e SHOW_POSIX_ATTRIBUTES=TRUE \
-e LDAP_URI=ldaps://ldap.acsalab.com \
-e LDAP_BASE_DN="dc=acsa" \
-e LDAP_REQUIRE_STARTTLS=TRUE \
-e LDAP_TLS_CACERT_FILE=/run/ldap/server.crt \
-e LDAP_IGNORE_CERT_ERRORS=TRUE \
-e LDAP_USER_OU=user \
-e LDAP_GROUP_OU=group \
-e DEFAULT_USER_GROUP=acsastaff \
-e LDAP_ADMINS_GROUP=sudo \
-e LDAP_ADMIN_BIND_DN="cn=admin,dc=acsa" \
-e LDAP_ADMIN_BIND_PWD_FILE=/run/secrets/ldap/secret \
-e EMAIL_DOMAIN=acsalab.com \
-e LDAP_VERBOSE_CONNECTION_LOGS=TRUE \
wheelybird/ldap-user-manager:v1.11
Then we can visit https://ldap.acsalab.com to manage users and groups.
Do not create users with web UI
Due to its own limitations, users created in the web UI will not have their Samba attributes populated, and thus will not be able to access our Synology NAS via SMB or OpenVPN. Create users using the LDAP command-line tools instead.
Client¶
Configuring an Ubuntu or Debian server to use LDAP:
Install libnss-ldapd
with all recommended packages (just don't add --no-install-recommends
).
When configuring libnss-ldapd
, select the first three items (passwd, group, shadow) and continue.
Check /etc/nsswitch.conf
to ensure ldap
appears after passwd
, group
and shadow
lines.
Copy /etc/ldap/ca.crt
from another machine or just download (wget / curl) from here.
/etc/ldap/ldap.conf¶
Edit this file and set the following keys:
BASE dc=acsa
URI ldaps://ldap.acsalab.com
TLS_CACERT /etc/ldap/ca.crt
/etc/nslcd.conf¶
This is the most important file. Edit the content for the following settings:
uri ldaps://ldap.acsalab.com
base dc=acsa
ssl on
tlq_reqcert demand
tls_cacertfile /etc/ldap/ca.crt
Everything else can be left as-is.
Restart both nscd
and nslcd
services. Now you can check the output of getent passwd
to see if any additional entries show up.
PAM¶
Finally, append to the end of /etc/pam.d/common-session
this line:
session required pam_mkhomedir.so skel=/etc/skel umask=0022
This makes sure whoever doesn't have a home directory gets created on their first login.
Notes¶
Broken chsh
The chsh
command doesn't work for LDAP users, while the chsh.ldap
command in Ubuntu 20.04 is broken. (LP#1892482)
Fix: Manually apply this commit to the local installation of /usr/share/nslcd-utils
.
Note:: Ubuntu 22.04 has the bug fixed already and chsh.ldap
works fine out of the box.
Synology LDAP
By default Synology syncs user/group info from LDAP server every 1440 minutes (24 hours). This means that any changes made to LDAP server will not be reflected on the NAS until the next sync. Notably, this includes newly added users (but not password changes). This has caused confusion for new users when connecting to OpenVPN on Synology.
We have since changed that setting (Domain/LDAP → Edit → Advanced) to 5 minutes. Any new Synology systems joining our LDAP should have this setting applied manually.