Files

16 KiB

title, author, license, description, overview, tags, categories, type, difficulty, cybok
title author license description overview tags categories type difficulty cybok
LDAP Authentication Setup Guide
Z. Cliffe Schreuders
CC BY-SA 4.0 Learn how to set up centralised LDAP authentication between an OpenLDAP server and Linux clients using nslcd and PAM for enterprise identity management. This lab provides a comprehensive guide to setting up LDAP (Lightweight Directory Access Protocol) authentication in a networked environment. You will learn how to configure an OpenLDAP server using phpLDAPadmin for user management, and configure Linux client systems to authenticate against the LDAP directory using nslcd. The lab covers creating organisational units, POSIX groups, and user accounts with proper UID/GID management to avoid conflicts with local users. You will also learn how to configure NSS (Name Service Switch) and PAM (Pluggable Authentication Modules) to enable centralised authentication and automatic home directory creation. By the end of this lab, you will understand the fundamentals of directory services and centralised authentication, which are essential components of enterprise identity management systems.
ldap
authentication
identity-management
openldap
nslcd
pam
directory-services
phpldapadmin
linux
systems_security
lab-sheet
intermediate
ka topic keywords
AAA Authentication
identity management
user authentication
facets of authentication
authentication in distributed systems
ka topic keywords
AAA Authorisation
AUTHORIsATION - LDAP (LIGHTWEIGHT DIRECTORY ACCESS PROTOCOL)

LDAP Authentication Setup Guide

This guide will walk you through setting up LDAP authentication between the auth_servr (LDAP server) and staff_desktop (LDAP client).

Overview

  • auth_server: Running OpenLDAP server (slapd) with phpLDAPadmin web interface
  • staff_desktop: Desktop system that will authenticate against LDAP

Step 1: Find the auth_server IP Address

  1. ==VM: Log in to auth_server==

  2. ==action: Find the IP address:==

ip addr show \| grep "inet "

Or simply:

hostname -I
  1. ==action: Note this IP address== - you'll need it for the client configuration later

Example output might be: 10.9.8.7

Note: Throughout this guide, replace <AUTH_SERVER_IP> with your actual auth_server IP address.

Step 2: Access phpLDAPadmin

  1. ==VM: On the auth_server==, ==action: open a web browser==

  2. ==action: Navigate to the phpLDAPadmin web interface:==

http://localhost/phpldapadmin/
  1. You should see the phpLDAPadmin login page

Step 3: Log in to phpLDAPadmin

  1. ==action: Click on "login" in the left sidebar== (or look for the login section)

  2. ==action: Enter the administrator credentials:==

    • Login DN: cn=admin,dc=safetynet,dc=local
    • Password: tiaspbiqe2r
  3. ==action: Click "Authenticate"==

  4. You should now see the LDAP directory tree on the left, with dc=safetynet,dc=local as the root

Step 3.5: Verify phpLDAPadmin Auto-Increment UIDs Configuration

The ldap_server SecGen module has already configured phpLDAPadmin to auto-increment UIDs starting at 10000 instead of the default 1000. This avoids conflicts with local system users (which typically use UIDs 1000-9999).

==VM: You can verify this configuration on the auth_server:==

sudo grep "auto_number.*uidNumber" /etc/phpldapadmin/config.php

You should see:

$servers->setValue('auto_number','min',array('uidNumber'=>10000,'gidNumber'=>500));

This means when you create new LDAP users, phpLDAPadmin will automatically assign UIDs starting from 10000, 10001, 10002, etc.

Note: If for some reason the configuration wasn't applied, you can manually edit /etc/phpldapadmin/config.php and change the uidNumber value from 1000 to 10000.

Step 4: Create Organisational Units

Before creating users, it's good practice to organise your directory structure.

  1. ==action: Click on dc=safetynet,dc=com in the tree==

Tip: It's safe to ignore the "Automatically removed objectClass from template" messages.

  1. ==action: Click "Create a child entry"==

  2. ==action: Select "Generic: Organisational Unit"==

  3. ==action: Enter the OU name: "people"==

  4. ==action: Click "Create Object" then "Commit"==

  5. ==action: Repeat steps 1-5 to create another OU named "groups"==

Your directory structure should now look like:

dc=safetynet,dc=local
├── ou=people
└── ou=groups

Step 5: Create a Posix Group

Before creating users, you need to create at least one group for them to belong to.

  1. ==action: Click on "ou=groups" in the tree==

  2. ==action: Click "Create a child entry"==

  3. ==action: Select "Generic: Posix Group"==

  4. ==action: Fill in the group details:==

    • Group name (cn): staff
    • GID Number: 500
  5. ==action: Click "Create Object" then "Commit"==

Your group DN will be: cn=staff,ou=groups,dc=safetynet,dc=local

Step 6: Create an LDAP User

  1. ==action: Click on ou=people in the tree==

  2. ==action: Click "Create a child entry"==

  3. ==action: Select "Generic: User Account"==

  4. ==action: Fill in the user details:==

    • First name: John
    • Last name: Doe
    • Common Name: John Doe
    • User ID: jdoe
    • Password: tiaspbiqe2r ==warning: ← CRITICAL: Must set password!==
  5. ==action: Scroll down and verify/edit additional required attributes:==

    • uidNumber: Should be automatically set to 10000 (or next available). This is configured to start at 10000+ to avoid conflicts with local system users
    • gidNumber: 500 (Linux group ID - use the GID number from the staff group you created)
    • Home Directory: /home/jdoe
    • Login Shell: /bin/bash

Warning: The Password field is REQUIRED - authentication will fail if not set. The uidNumber should automatically be 10000 or higher (configured in Step 3.5). If it shows 1000, manually change it to 10000. All POSIX attributes (uidNumber, gidNumber, loginShell, homeDirectory) are REQUIRED for system login to work.

  1. ==action: Click "Create Object" then "Commit"==

Your user DN will be: uid=jdoe,ou=people,dc=safetynet,dc=local

  1. ==action: Verify the user was created correctly:==

==VM: On the auth_server==, ==action: test the user exists with all required attributes:==

ldapsearch -x -H ldap://localhost -b "dc=safetynet,dc=local" "(uid=jdoe)" uidNumber gidNumber loginShell homeDirectory userPassword

You should see:

uidNumber: 10000
gidNumber: 500
loginShell: /bin/bash
homeDirectory: /home/jdoe

Warning: uidNumber should be 10000+ to avoid conflicts with local users. If any attributes are missing, go back to phpLDAPadmin and edit the user to add them.

Step 7: Configure LDAP Client Authentication on staff_desktop

Now we'll configure the staff_desktop to authenticate against the LDAP server using nslcd (the NSS LDAP daemon).

Note: Why nslcd? This guide uses nslcd because it's straightforward and easy to configure - just set the LDAP server IP and credentials, and it works. An alternative is SSSD (System Security Services Daemon), which offers more advanced features like offline caching and multiple identity providers, but is more complex to set up. For this lab, nslcd is the simpler, more direct approach.

7.1: Install Required Packages (already done for you)

Hacktivity/SecGen has already installed:

  • ldap-utils (LDAP command-line tools)
  • libnss-ldap (NSS module for LDAP lookups)
  • libpam-ldap (PAM module for LDAP authentication)
  • nslcd (NSS LDAP connection daemon)
  • nscd (Name Service Cache Daemon)
  • sssd (alternative daemon, not used in this guide)

7.2: Configure nslcd

The nslcd daemon handles LDAP queries for the system. Configure it to connect to your auth_server:

  1. ==VM: SSH or log in to staff_desktop==

  2. ==action: Edit the nslcd configuration:==

sudo nano /etc/nslcd.conf
  1. ==action: Find and update the following lines (or add them if missing):==
uri ldap://==edit:<AUTH_SERVER_IP>==
base dc=safetynet,dc=local

# Bind credentials for searching LDAP
binddn cn=admin,dc=safetynet,dc=local
bindpw tiaspbiqe2r

Note: Replace <AUTH_SERVER_IP> with your actual auth_server IP from Step 1.

  1. ==action: Save and exit (Ctrl+X, Y, Enter)==

7.3: Configure NSS to use LDAP

Edit the Name Service Switch configuration to use LDAP:

  1. ==action: Edit /etc/nsswitch.conf:==
sudo nano /etc/nsswitch.conf
  1. ==action: Update the passwd, group, and shadow lines to include ldap:==
passwd:         compat systemd ldap
group:          compat systemd ldap
shadow:         compat ldap

Note: This tells the system to check local files first, then query LDAP for user/group information.

  1. ==action: Save and exit (Ctrl+X, Y, Enter)==

7.4: Restart nslcd Service

  1. ==action: Restart the nslcd daemon to apply the configuration:==
sudo systemctl restart nslcd
sudo systemctl enable nslcd
  1. ==action: Check that nslcd is running:==
sudo systemctl status nslcd

Note: Should show active (running).

7.5: Enable PAM Authentication

==action: Configure PAM to create home directories automatically:==

sudo pam-auth-update

==action: Make sure the following are enabled (marked with [*]):==

  • Unix authentication
  • LDAP Authentication
  • Create home directory on login

Tip: Use spacebar to toggle, then Tab to OK, and Enter to save.

7.6: Verify LDAP User Lookup

==action: Test that the LDAP user can be retrieved:==

getent passwd jdoe

You should see output like:

jdoe:*:10000:500:John Doe:/home/jdoe:/bin/bash

Note: The UID should be 10000+ (LDAP user range).

Warning: If you see nothing, nslcd isn't connecting to LDAP properly. Check:

  • The auth_server IP is correct in /etc/nslcd.conf
  • The LDAP server is reachable: ping <AUTH_SERVER_IP>
  • The bind credentials are correct in /etc/nslcd.conf
  • Test LDAP directly: ldapsearch -x -H ldap://<AUTH_SERVER_IP> -b "dc=safetynet,dc=local" "(uid=jdoe)"
  • Check nslcd logs: sudo journalctl -u nslcd -n 50

Warning: If getent passwd jdoe returns nothing, fix the issue before proceeding to authentication testing.

Step 8: Test LDAP Authentication

Now that nslcd is configured and can retrieve the user (verified in Step 7.6), test authentication:

  1. ==action: Try to log in as the LDAP user:==
su - jdoe
  1. ==action: Enter the password you set in phpLDAPadmin== (e.g., tiaspbiqe2r)

  2. If successful, you should be logged in as jdoe with a home directory automatically created at /home/jdoe

  3. ==action: Verify with:==

whoami    # Should output: jdoe
pwd       # Should output: /home/jdoe
id        # Should show UID 10000, GID 500

Success! You're now authenticated via LDAP!

Step 9: Troubleshooting

Check LDAP Server Status

==VM: On auth_server:==

sudo systemctl status slapd
sudo slapcat \| head -20

Check Client Configuration

==VM: On staff_desktop:==

# Check nslcd status
sudo systemctl status nslcd

# Check nslcd logs
sudo journalctl -u nslcd -n 50

# Test LDAP connectivity
ldapsearch -x -H ldap://==edit:<AUTH_SERVER_IP>== -b "dc=safetynet,dc=local"

# Check authentication logs
sudo tail -50 /var/log/auth.log

# Test user lookup
getent passwd jdoe

Common Issues

  1. "nslcd: Can't contact LDAP server" / "failed to bind to LDAP server ldap://127.0.0.1/":

    The nslcd service is trying to connect to localhost instead of your auth_server.

    Fix: ==action: Update /etc/nslcd.conf with the correct server IP:==

sudo nano /etc/nslcd.conf

==action: Make sure these lines are correct:==

uri ldap://==edit:<AUTH_SERVER_IP>==
base dc=safetynet,dc=local
binddn cn=admin,dc=safetynet,dc=local
bindpw tiaspbiqe2r

Note: Replace <AUTH_SERVER_IP> with your actual auth_server IP address.

==action: Then restart nslcd:==

sudo systemctl restart nslcd
sudo systemctl status nslcd
  1. "User not found" / getent passwd jdoe returns nothing:

Hint: Verify LDAP server is running on auth_server: sudo systemctl status slapd

  • Test connectivity from staff_desktop: ldapsearch -x -H ldap://<AUTH_SERVER_IP> -b "dc=safetynet,dc=local" "(uid=jdoe)"
  • Check nslcd is running: sudo systemctl status nslcd
  • Check nslcd logs: sudo journalctl -u nslcd -n 50
  • Verify /etc/nslcd.conf has correct server IP and bind credentials
  • Restart nslcd: sudo systemctl restart nslcd
  1. "Authentication failure" / Wrong password:

    If getent passwd jdoe works but su - jdoe fails with wrong password:

    ==action: Test LDAP authentication directly:==

ldapwhoami -x -H ldap://==edit:<AUTH_SERVER_IP>== -D "cn=John Doe,ou=people,dc=safetynet,dc=local" -W

Or if the DN is uid=jdoe:

ldapwhoami -x -H ldap://==edit:<AUTH_SERVER_IP>== -D "uid=jdoe,ou=people,dc=safetynet,dc=local" -W

==action: Enter the password when prompted.==

Note: If this succeeds: Password is correct, issue is with PAM/nslcd configuration. If this fails with "Invalid credentials": Password is wrong or not set in phpLDAPadmin.

==action: Check the user has a password set:==

ldapsearch -x -H ldap://==edit:<AUTH_SERVER_IP>== -b "dc=safetynet,dc=local" "(uid=jdoe)" userPassword

Note: Should show: userPassword: {SSHA}... or {MD5}.... If empty, set the password in phpLDAPadmin.

  1. PAM configuration issues:

==action: Run:==

sudo pam-auth-update

==action: Make sure these are enabled (marked with [*]):==

  • Unix authentication
  • LDAP Authentication
  • Create home directory on login
  1. Home directory not created:

Hint: Ensure "Create home directory on login" is enabled in PAM. Check PAM configuration: sudo pam-auth-update. Or manually add to PAM config: session required pam_mkhomedir.so skel=/etc/skel umask=0022

Step 10: Additional Tasks

Create Additional Users

==action: Repeat Step 6 to create more users with different UIDs (10001, 10002, 10003, etc.)==

Tip: phpLDAPadmin will auto-increment UIDs starting from 10000.

Create LDAP Groups

  1. ==action: In phpLDAPadmin, click on ou=groups==
  2. ==action: Create a child entry==
  3. ==action: Select "Generic: Posix Group"==
  4. ==action: Set group name (e.g., "developers")==
  5. ==action: After creating the group, add members:==
    • Click on the group entry
    • Add attribute: memberUid
    • Enter username: jdoe
    • Click "Update Object"
    • Repeat to add more members

Advanced: Use SSSD Instead of nslcd (Optional)

For an advanced exercise, you could choose to configure SSSD instead of nslcd:

  1. ==action: Stop and disable nslcd:==
sudo systemctl stop nslcd
sudo systemctl disable nslcd
  1. ==action: Create /etc/sssd/sssd.conf:==
[sssd]
services = nss, pam
config_file_version = 2
domains = safetynet.local

[domain/safetynet.local]
id_provider = ldap
auth_provider = ldap
access_provider = permit
ldap_uri = ldap://==edit:<AUTH_SERVER_IP>==
ldap_search_base = dc=safetynet,dc=local
ldap_default_bind_dn = cn=admin,dc=safetynet,dc=local
ldap_default_authtok = tiaspbiqe2r
ldap_id_use_start_tls = false
ldap_tls_reqcert = never
  1. ==action: Set permissions and restart:==
sudo chmod 600 /etc/sssd/sssd.conf
sudo systemctl restart sssd
sudo systemctl enable sssd
  1. ==action: Update /etc/nsswitch.conf to use sss instead of ldap:==
passwd:         files systemd sss
group:          files systemd sss
shadow:         files sss
  1. ==action: Test:==
getent passwd jdoe
su - jdoe

Note: Why use SSSD? It provides offline authentication caching, better performance, and supports multiple identity providers (LDAP, AD, Kerberos). However, it's more complex to configure -- and these instructions are likely an incomplete starting point.

Security Considerations

Warning: For production environments, consider the following security enhancements:

  • LDAPS: Enable TLS/SSL (ldaps://)
  • Strong Passwords: Enforce password policies in LDAP
  • Access Control: Use LDAP ACLs to restrict who can read/modify entries
  • Firewall: Restrict LDAP port (389) access to authorised systems only
  • Monitoring: Monitor authentication logs for suspicious activity

Conclusion

You now have a working LDAP authentication system where:

  • Users are stored centrally on the auth_server
  • The staff_desktop authenticates users against LDAP
  • User accounts are managed through phpLDAPadmin
  • Home directories are created automatically on first login

This setup demonstrates centralised authentication, a key component of enterprise identity management systems.