Merge pull request 'Location' (#5) from location into master

Reviewed-on: #5
This commit was merged in pull request #5.
This commit is contained in:
2026-07-11 17:00:34 +00:00
10 changed files with 2032 additions and 844 deletions
+255 -6
View File
@@ -1,11 +1,260 @@
# LDAP client script for ubuntu/debian # LDAP Client
## Usage Bash-based SSSD LDAP authentication client for Ubuntu/Debian systems. Integrates with [theta42/sso-manager-node](https://github.com/theta42/sso-manager-node) for centralized user management, group-based access control, and SSH key distribution.
Move into the repo root ## Overview
Copy the file ldap.vars.template to ldap.vars This script automates the configuration of SSSD (System Security Services Daemon) to provide:
Edit ldap.vars to your liking - LDAP authentication against a central directory
- Group-based access control (only authorized users can log in)
- Sudo privileges via LDAP groups
- SSH public key retrieval from LDAP for key-based authentication
- Automatic home directory creation for LDAP users
- Optional registration of host-specific groups via the SSO Manager API
Execute ./index.sh ## Prerequisites
- Ubuntu or Debian system with root access
- Network connectivity to your LDAP server (LDAPS on port 636)
- LDAP service account credentials
- CA certificates for LDAP TLS validation
- (Optional) SSO Manager instance for group API registration
## Installation
### 1. Clone the repository
```bash
git clone https://github.com/theta42/ldap-client.git
cd ldap-client
```
### 2. Create configuration
Copy the template configuration file:
```bash
cp ldap.vars.template ldap.vars
```
### 3. Configure variables
Edit `ldap.vars` with your environment settings:
```bash
# LDAP server settings
export ldap_host="ldap.internal.theta42.com"
export ldap_base_dn="dc=theta42,dc=com"
# Service account for LDAP binds
export ldap_bind_dn="cn=ldapclient service,ou=People,$ldap_base_dn"
export ldap_bind_password="your-service-account-password"
# SSO Manager integration (optional)
export sso_url="https://sso.theta42.com"
export sso_token="your-api-token"
# Location identifier for group naming (optional)
export ldap_location="718it"
```
#### Variable descriptions
| Variable | Required | Description |
|----------|----------|-------------|
| `ldap_host` | Yes | LDAP server hostname |
| `ldap_base_dn` | Yes | Base DN for LDAP searches |
| `ldap_bind_dn` | Yes | DN of the service account for LDAP binds |
| `ldap_bind_password` | Yes | Password for the service account |
| `sso_url` | No | Base URL of the SSO Manager API |
| `sso_token` | No | API authentication token for SSO Manager |
| `ldap_location` | No | Location prefix for group names (e.g., `718it`). If omitted, group-based access control will not be configured |
#### Group configuration
The script uses two arrays to define which LDAP groups grant access:
```bash
ldap_access_groups=( "${ldap_location}_access" "${ldap_location}_$(hostname)_access" )
ldap_sudo_groups=( "${ldap_location}_admin" "${ldap_location}_$(hostname)_admin" )
```
This creates both location-wide and host-specific groups:
- `718it_access` - grants login access to all hosts in this location
- `718it_host_webserver01_access` - grants login access only to webserver01
- `718it_admin` - grants sudo privileges on all hosts
- `718it_host_webserver01_admin` - grants sudo privileges only on webserver01
If `ldap_location` is not set, these arrays will be empty and access control will be handled entirely by LDAP-side configuration.
### 4. Run the installation script
```bash
sudo ./index.sh
```
The script will:
1. Install required packages (sssd, sssd-ldap, libnss-sss, libpam-sss, ldap-utils, libsss-sudo)
2. Generate and deploy the SSSD configuration
3. Configure NSS to use SSS for passwd, group, and sudoers lookups
4. Enable automatic home directory creation via PAM
5. Deploy the SSH AuthorizedKeysCommand script
6. Configure SSHD to retrieve keys from LDAP
7. (Optional) Register host-specific groups with the SSO Manager API
8. Start and enable the SSSD service
## Post-installation verification
### Test LDAP user lookup
```bash
getent passwd <ldap-username>
```
### Test group membership
```bash
getent group <group-name>
```
### Test sudo access
```bash
sudo -l -U <ldap-username>
```
### Test SSH key retrieval
```bash
/usr/local/bin/ldap-ssh-key <ldap-username>
```
### Check SSSD status
```bash
systemctl status sssd
journalctl -u sssd -f
```
### Verify authentication
```bash
su - <ldap-username>
```
## File structure
```
ldap-client/
index.sh # Main installation script
ldap.vars.template # Configuration template (copy to ldap.vars)
ldap.vars.theta42 # Example configuration for theta42
files/
sssd.conf.mo # SSSD configuration template (Mustache)
ldap-ssh-key.sh # SSH AuthorizedKeysCommand script
sudo-ldap.conf # LDAP sudo configuration template
lib/
mo # Mustache template processor
```
## How it works
### Authentication flow
1. User attempts to log in via SSH or console
2. PAM/SSSD queries LDAP for user credentials
3. If user is in an authorized access group, authentication proceeds
4. Home directory is created automatically on first login (via pam_mkhomedir)
### SSH key distribution
1. SSHD calls `/usr/local/bin/ldap-ssh-key` with the username
2. The script queries LDAP for the user's `sshPublicKey` attribute
3. Keys are returned to SSHD for authentication
4. This allows SSH key management through the central directory
### Sudo integration
SSSD is configured with an LDAP sudo provider that:
- Searches for sudo rules in the LDAP directory
- Filters rules based on group membership
- Refreshes rules every 15 minutes (full) or 5 minutes (smart)
### SSO Manager integration
When `sso_token` is configured, the script automatically creates host-specific groups in the SSO Manager:
- `<location>_host_<hostname>_access` - for login access
- `<location>_host_<hostname>_admin` - for sudo privileges
This allows you to manage host-specific access through the SSO Manager web interface.
## Troubleshooting
### SSSD not starting
Check the configuration syntax:
```bash
sssd --genconf-only
```
Review logs:
```bash
journalctl -u sssd -f
```
### Users cannot authenticate
1. Verify LDAP connectivity:
```bash
ldapsearch -H ldaps://<ldap_host> -b "<ldap_base_dn>" -D "<bind_dn>" -W
```
2. Check group membership in LDAP
3. Verify the `ldap_access_filter` in `/etc/sssd/sssd.conf`
### SSH keys not working
1. Test the key retrieval script directly:
```bash
/usr/local/bin/ldap-ssh-key <username>
```
2. Verify `sshPublicKey` attribute exists in LDAP
3. Check SSHD configuration:
```bash
sshd -T | grep authorizedkeys
```
### Sudo rules not applying
1. Check sudo provider configuration in `/etc/sssd/sssd.conf`
2. Verify sudo rules exist in LDAP with correct host and group filters
3. Force SSSD refresh:
```bash
sssctl cache-expire --group
systemctl restart sssd
```
## Security considerations
- The LDAP bind password in `ldap.vars` should have restricted filesystem permissions
- SSSD configuration (`/etc/sssd/sssd.conf`) is set to mode 600
- LDAPS (TLS) is required for LDAP connections
- The SSH key script runs as the `nobody` user for minimal privilege
## Related projects
- [theta42/sso-manager-node](https://github.com/theta42/sso-manager-node) - Centralized SSO and LDAP management
## License
This project is provided as-is for internal use.
+1 -1
View File
@@ -4,6 +4,6 @@ ldapsearch -H "ldap://{{ldap_host}}" \
-D "{{ldap_bind_dn}}" \ -D "{{ldap_bind_dn}}" \
-w "{{ldap_bind_password}}" \ -w "{{ldap_bind_password}}" \
-b "ou=People,{{ldap_base_dn}}" \ -b "ou=People,{{ldap_base_dn}}" \
"(&(uid=$1)(|(memberof=cn=host_access,ou=Groups,{{ldap_base_dn}})(memberof=cn=host_{{current_host}}_access,ou=Groups,{{ldap_base_dn}})))" \ "(&(uid=$1)(|{{#ldap_access_groups}}(memberof={{.}},ou=Groups,{{ldap_base_dn}}){{/ldap_access_groups}}))" \
'*' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;s/sshPublicKey: //gp' '*' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;s/sshPublicKey: //gp'
+2 -2
View File
@@ -21,12 +21,12 @@ ldap_sudo_search_base = {{ldap_base_dn}}
# Filter for sudo access: global host_admin OR host-specific admin # Filter for sudo access: global host_admin OR host-specific admin
ldap_sudo_full_refresh_interval = 900 ldap_sudo_full_refresh_interval = 900
ldap_sudo_smart_refresh_interval = 300 ldap_sudo_smart_refresh_interval = 300
ldap_sudo_search_filter = (|(memberOf=cn=host_admin,ou=groups,dc=theta42,dc=com)(memberOf=cn=host_{hostname}_admin,ou=groups,dc=theta42,dc=com)) ldap_sudo_search_filter = (|(memberOf=cn={{location}}host_admin,ou=groups,dc=theta42,dc=com)(memberOf=cn={{location}}host_{hostname}_admin,ou=groups,dc=theta42,dc=com))
# Access control: only allow users in host_access or host_{hostname}_access # Access control: only allow users in host_access or host_{hostname}_access
access_provider = ldap access_provider = ldap
ldap_access_order = filter ldap_access_order = filter
ldap_access_filter = (|(memberof=cn=host_access,ou=groups,{{ldap_base_dn}})(memberof=cn=host_{{current_host}}_access,ou=groups,{{ldap_base_dn}})) ldap_access_filter = (|(memberof=cn={{location}}host_access,ou=groups,{{ldap_base_dn}})(memberof=cn={{location}}host_{{current_host}}_access,ou=groups,{{ldap_base_dn}}))
# Mapping # Mapping
ldap_user_search_base = ou=people,{{ldap_base_dn}} ldap_user_search_base = ou=people,{{ldap_base_dn}}
+1 -1
View File
@@ -6,4 +6,4 @@ BINDPW {{ldap_bind_password}}
sudoers_base {{ldap_base_dn}} sudoers_base {{ldap_base_dn}}
SUDOERS_SEARCH_FILTER (|(memberof=cn=host_admin,ou=Groups,{{ldap_base_dn}})(memberof=cn=host_{{current_host}}_admin,ou=Groups,{{ldap_base_dn}})) SUDOERS_SEARCH_FILTER (|{{#ldap_sudo_groups}}(memberof={{.}},ou=Groups,{{ldap_base_dn}}){{/ldap_sudo_groups}})
+2 -2
View File
@@ -56,12 +56,12 @@ if [[ -v sso_token ]]; then
curl "${sso_url}/api/group/" \ curl "${sso_url}/api/group/" \
-H "auth-token: ${sso_token}" \ -H "auth-token: ${sso_token}" \
-H "content-type: application/json; charset=UTF-8" \ -H "content-type: application/json; charset=UTF-8" \
--data-binary "{\"name\":\"host_${current_host}_access\",\"description\":\"Access for $current_host\"}" --data-binary "{\"name\":\"${ldap_location}_host_${current_host}_access\",\"description\":\"Access for $current_host\"}"
curl "${sso_url}/api/group/" \ curl "${sso_url}/api/group/" \
-H "auth-token: ${sso_token}" \ -H "auth-token: ${sso_token}" \
-H "content-type: application/json; charset=UTF-8" \ -H "content-type: application/json; charset=UTF-8" \
--data-binary "{\"name\":\"host_${current_host}_admin\",\"description\":\"sudo for $current_host\"}" --data-binary "{\"name\":\"${ldap_location}_host_${current_host}_admin\",\"description\":\"sudo for $current_host\"}"
fi fi
echo "--- SSSD Migration Complete! ---" echo "--- SSSD Migration Complete! ---"
+14
View File
@@ -0,0 +1,14 @@
# Set some variables for the test of the file
export ldap_host="ldap.internal.theta42.com"
export ldap_base_dn="dc=theta42,dc=com"
export ldap_bind_dn="cn=ldapclient service,ou=People,$ldap_base_dn"
export ldap_bind_password=""
export sso_url="https://sso.theta42.com"
export sso_token="" # This is the only optional variable
export ldap_location="pdp"
ldap_access_groups=( "${ldap_location}_access" "${ldap_location}_$(hostname)_access" )
ldap_sudo_groups=( "${ldap_location}_admin" "${ldap_location}_$(hostname)_admin" )
+7 -5
View File
@@ -1,12 +1,14 @@
# Set some variables for the test of the file # Set some variables for the test of the file
export ldap_host="10.1.0.55" export ldap_host="ldap.internal.theta42.com"
export ldap_base_dn="dc=theta42,dc=com" export ldap_base_dn="dc=theta42,dc=com"
export ldap_admin_dn="cn=admin,$ldap_base_dn"
export ldap_admin_password=""
export ldap_bind_dn="cn=ldapclient service,ou=People,$ldap_base_dn" export ldap_bind_dn="cn=ldapclient service,ou=People,$ldap_base_dn"
export ldap_bind_password="" export ldap_bind_password=""
export sso_url="https://sso.theta42.com" export sso_url="https://sso.theta42.com"
export sso_token="uuid_thingy" # This is the only optional variable export sso_token="" # This is the only optional variable
export ldap_location=""
ldap_access_groups=( "${ldap_location}_access" "${ldap_location}_$(hostname)_access" )
ldap_sudo_groups=( "${ldap_location}_admin" "${ldap_location}_$(hostname)_admin" )
+6 -1
View File
@@ -6,4 +6,9 @@ export ldap_bind_dn="cn=ldapclient service,ou=People,$ldap_base_dn"
export ldap_bind_password="" export ldap_bind_password=""
export sso_url="https://sso.theta42.com" export sso_url="https://sso.theta42.com"
export sso_token="" # This is the only optional variable export sso_token="" # This is the only optional variable
export ldap_location="718it"
ldap_access_groups=( "${ldap_location}_access" "${ldap_location}_$(hostname)_access" )
ldap_sudo_groups=( "${ldap_location}_admin" "${ldap_location}_$(hostname)_admin" )
+1744 -768
View File
File diff suppressed because it is too large Load Diff
-58
View File
@@ -1,58 +0,0 @@
#!/bin/bash
set -e
# Pull in the mustache template library for bash
source lib/mo
if [ ! -f ./ldap.vars ]; then
echo "ldap.vars file not found!"
echo "Please copy ldap.vars.template to ldap.vars and edit it."
exit 1
fi
source ldap.vars
export current_host=$(hostname)
echo "--- Starting LDAP to SSSD Migration ---"
echo "1. Cleaning up old LDAP configuration and packages..."
# 1. Remove old packages (libnss-ldap, libpam-ldap, sudo-ldap, nscd, etc.)
DEBIAN_FRONTEND=noninteractive apt purge -y libnss-ldap libpam-ldap nscd sudo-ldap nslcd
# Preserve ldap-utils if it's still useful for general LDAP querying
# apt purge -y ldap-utils
# 2. Clean up old configuration files
echo " - Removing old configuration files..."
rm -f /etc/pam_ldap.conf
rm -f /etc/ldap/ldap.conf
rm -f /etc/ldap.conf
rm -f /etc/sudo-ldap.conf
# 3. Revert nsswitch.conf entries related to 'ldap'
echo " - Reverting /etc/nsswitch.conf entries for 'ldap'..."
sed -i '/passwd:/ s/ ldap//' /etc/nsswitch.conf
sed -i '/group:/ s/ ldap//' /etc/nsswitch.conf
# You might want to review other services like 'shadow' or 'hosts' if they also had 'ldap'
# For example: sed -i '/shadow:/ s/ ldap//' /etc/nsswitch.conf
# 4. Clean up PAM configurations
echo " - Cleaning up old PAM configurations..."
# Disable 'ldap' in pam-auth-update if it was enabled directly
pam-auth-update --remove ldap
# Remove specific common-password modifications made by the old script
# The old script removed 'use_authtok'. Let's ensure a clean state if SSSD needs a different one.
# It's generally safer to restore from a backup or let the new SSSD setup configure PAM.
# For simplicity, we'll rely on the new sssd pam module to set things correctly.
sed -i '/session required pam_mkhomedir.so skel=\/etc\/skel umask=077/d' /etc/pam.d/common-session
# Ensure nscd is stopped and disabled if it wasn't purged
systemctl stop nscd || true
systemctl disable nscd || true
echo "Cleanup complete."
echo "--- Installing New SSSD Configuration ---"
./index.sh