diff --git a/_labs/systems_security/3_ldap_setup.md b/_labs/systems_security/3_ldap_setup.md new file mode 100644 index 0000000..5bc5c22 --- /dev/null +++ b/_labs/systems_security/3_ldap_setup.md @@ -0,0 +1,529 @@ +# 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:== + +```bash +ip addr show \| grep "inet " +``` + +Or simply: + +```bash +hostname -I +``` + +3. ==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 `` 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/ +``` + +3. 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`:== + +```bash +sudo grep "auto_number.*uidNumber" /etc/phpldapadmin/config.php +``` + +You should see: + +```php +$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 Organizational Units + +Before creating users, it's good practice to organize 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. + +2. ==action: Click "Create a child entry"== + +3. ==action: Select "Generic: Organisational Unit"== + +4. ==action: Enter the OU name: `people`== + +5. ==action: Click "Create Object" then "Commit"== + +6. ==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. + +> Note: REVIEW NOTE: The 1000 rule hasn't been set in the config file + +6. ==action: Click "Create Object" then "Commit"== + +Your user DN will be: `uid=jdoe,ou=people,dc=safetynet,dc=local` + +7. ==action: Verify the user was created correctly:== + +==VM: On the `auth_server`==, ==action: test the user exists with all required attributes:== + +```bash +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) + +The `ldap_packages` SecGen module 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:== + +```bash +sudo nano /etc/nslcd.conf +``` + +3. ==action: Find and update the following lines (or add them if missing):== + +``` +uri ldap://==edit:== +base dc=safetynet,dc=local + +# Bind credentials for searching LDAP +binddn cn=admin,dc=safetynet,dc=local +bindpw tiaspbiqe2r +``` + +> Note: Replace `` with your actual auth_server IP from Step 1. + +4. ==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`:== + +```bash +sudo nano /etc/nsswitch.conf +``` + +2. ==action: Update the `passwd`, `group`, and `shadow` lines to include `ldap`:== + +``` +passwd: files systemd ldap +group: files systemd ldap +shadow: files ldap +``` + +> Note: This tells the system to check local files first, then query LDAP for user/group information. + +> Note: REVIEW NOTE: had compat rather than files? `passwd: compat systemd ldap`, `group: compat systemd ldap`, `shadow: compat ldap` + +3. ==action: Save and exit (Ctrl+X, Y, Enter)== + +### 7.4: Restart nslcd Service + +1. ==action: Restart the nslcd daemon to apply the configuration:== + +```bash +sudo systemctl restart nslcd +sudo systemctl enable nslcd +``` + +2. ==action: Check that nslcd is running:== + +```bash +sudo systemctl status nslcd +``` + +> Note: Should show `active (running)`. + +### 7.5: Enable PAM Authentication + +==action: Configure PAM to create home directories automatically:== + +```bash +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:== + +```bash +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 ` +> - The bind credentials are correct in `/etc/nslcd.conf` +> - Test LDAP directly: `ldapsearch -x -H ldap:// -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:== + +```bash +su - jdoe +``` + +2. ==action: Enter the password you set in phpLDAPadmin== (e.g., `tiaspbiqe2r`) + +3. If successful, you should be logged in as `jdoe` with a home directory automatically created at `/home/jdoe` + +4. ==action: Verify with:== + +```bash +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`:== + +```bash +sudo systemctl status slapd +sudo slapcat \| head -20 +``` + +### Check Client Configuration + +==VM: On `staff_desktop`:== + +```bash +# Check nslcd status +sudo systemctl status nslcd + +# Check nslcd logs +sudo journalctl -u nslcd -n 50 + +# Test LDAP connectivity +ldapsearch -x -H ldap://==edit:== -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:== + +```bash +sudo nano /etc/nslcd.conf +``` + +==action: Make sure these lines are correct:== + +``` +uri ldap://==edit:== +base dc=safetynet,dc=local +binddn cn=admin,dc=safetynet,dc=local +bindpw tiaspbiqe2r +``` + +> Note: Replace `` with your actual auth_server IP address. + +==action: Then restart nslcd:== + +```bash +sudo systemctl restart nslcd +sudo systemctl status nslcd +``` + +2. **"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:// -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` + +3. **"Authentication failure" / Wrong password**: + + If `getent passwd jdoe` works but `su - jdoe` fails with wrong password: + + ==action: Test LDAP authentication directly:== + +```bash +ldapwhoami -x -H ldap://==edit:== -D "cn=John Doe,ou=people,dc=safetynet,dc=local" -W +``` + +Or if the DN is `uid=jdoe`: + +```bash +ldapwhoami -x -H ldap://==edit:== -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:== + +```bash +ldapsearch -x -H ldap://==edit:== -b "dc=safetynet,dc=local" "(uid=jdoe)" userPassword +``` + +> Note: Should show: `userPassword: {SSHA}...` or `{MD5}...`. If empty, set the password in phpLDAPadmin. + +4. **PAM configuration issues**: + +==action: Run:== + +```bash +sudo pam-auth-update +``` + +==action: Make sure these are enabled (marked with `[*]`):== +- `Unix authentication` +- `LDAP Authentication` +- `Create home directory on login` + +5. **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:== + +```bash +sudo systemctl stop nslcd +sudo systemctl disable nslcd +``` + +2. ==action: Create `/etc/sssd/sssd.conf`:== + +```ini +[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:== +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 +``` + +3. ==action: Set permissions and restart:== + +```bash +sudo chmod 600 /etc/sssd/sssd.conf +sudo systemctl restart sssd +sudo systemctl enable sssd +``` + +4. ==action: Update `/etc/nsswitch.conf` to use `sss` instead of `ldap`:== + +``` +passwd: files systemd sss +group: files systemd sss +shadow: files sss +``` + +5. ==action: Test:== + +```bash +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 authorized 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 centralized authentication, a key component of enterprise identity management systems.