OpenLDAP-Based Centralized Authentication Architecture (Part 4) — SUDO Policy Integration and Audit Log Centralization
1. Overview
This document explains how to centralize sudo privilege policies on an OpenLDAP server and collect command execution logs to a central log server using auditd and rsyslog.
It includes the creation and execution procedure of the sudoers2ldif script, which converts an existing /etc/sudoers file into LDAP format.
With this setup, all individual sudoers configurations are removed, allowing unified management via LDAP.
⚠️ Note:
All IPs, usernames, domain names, and hostnames in this document are examples only.
Modify them according to your organization’s security policy before deployment.
2. Architecture Overview
The LDAP-based sudo policy integration works as follows:
[Linux Client]
↓
/etc/sudo-ldap.conf
↓
[nsswitch.conf → sudoers: files ldap]
↓
[OpenLDAP Server]
├── sudo.schema
└── ou=sudo,ou=people,dc=example,dc=com
├── cn=defaults
├── cn=ops
└── cn=dev
Each client queries the LDAP server for sudo policy during execution.
Different privileges can be applied for operations or development teams.
3. Applying the SUDO Schema
Enable the sudoRole object in LDAP by adding the sudo.schema.
# cp /usr/share/doc/sudo*/schema.OpenLDAP /etc/openldap/schema/sudo.schema
# slapcat -f /etc/openldap/schema/sudo.schema -F /etc/openldap/slapd.d -n0 > /etc/openldap/ldif/sudo.ldif
# sed -i 's/{0}schema/sudo/g' /etc/openldap/ldif/sudo.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/ldif/sudo.ldif
After applying, you can add sudoRole objects to the directory.
4. Creating and Running the sudoers2ldif Script
4.1 Script Creation
If /usr/share/doc/sudo*/sudoers2ldif does not exist, create one manually:
# mkdir -p /usr/share/doc/sudo-custom
# vi /usr/share/doc/sudo-custom/sudoers2ldif
Insert the following content (as provided in the reference PPT):
#!/bin/bash
# sudoers2ldif - convert /etc/sudoers to LDIF format
# Author: example adaptation
SUDOERS=${1:-/etc/sudoers}
SUDOERS_BASE=${SUDOERS_BASE:-"ou=sudo,ou=people,dc=example,dc=com"}
echo "dn: $SUDOERS_BASE"
echo "objectClass: organizationalUnit"
echo "ou: sudo"
echo ""
grep -v -E '^#|^$' "$SUDOERS" | while read -r line; do
case "$line" in
Defaults*)
echo "dn: cn=defaults,$SUDOERS_BASE"
echo "objectClass: top"
echo "objectClass: sudoRole"
echo "cn: defaults"
echo "sudoOption: ${line#Defaults }"
echo ""
;;
*@*|ALL*)
user=$(echo "$line" | awk '{print $1}')
host=$(echo "$line" | awk '{print $2}')
cmd=$(echo "$line" | awk '{$1=$2=""; print $0}' | sed 's/^ //')
echo "dn: cn=$user,$SUDOERS_BASE"
echo "objectClass: top"
echo "objectClass: sudoRole"
echo "cn: $user"
echo "sudoUser: $user"
echo "sudoHost: $host"
echo "sudoCommand: $cmd"
echo "sudoOrder: 10"
echo ""
;;
esac
done
Make the script executable:
# chmod +x /usr/share/doc/sudo-custom/sudoers2ldif
4.2 Convert to LDIF
# export SUDOERS_BASE="ou=sudo,ou=people,dc=example,dc=com"
# /usr/share/doc/sudo-custom/sudoers2ldif /etc/sudoers > /etc/openldap/ldif/sudoers.ldif
The converted LDIF file will be saved as /etc/openldap/ldif/sudoers.ldif.
4.3 Example Output
dn: ou=sudo,ou=people,dc=example,dc=com
objectClass: organizationalUnit
ou: sudo
dn: cn=defaults,ou=sudo,ou=people,dc=example,dc=com
objectClass: top
objectClass: sudoRole
cn: defaults
sudoOption: env_reset
sudoOption: secure_path=/sbin:/bin:/usr/sbin:/usr/bin
dn: cn=%ops,ou=sudo,ou=people,dc=example,dc=com
objectClass: top
objectClass: sudoRole
cn: %ops
sudoUser: %ops
sudoHost: ALL
sudoRunAsUser: ALL
sudoCommand: ALL
sudoOrder: 1
4.4 Apply to LDAP Server
# ldapadd -x -W -D "cn=manager,dc=example,dc=com" -f /etc/openldap/ldif/sudoers.ldif
Verify:
# ldapsearch -x -LLL -b "ou=sudo,ou=people,dc=example,dc=com" cn sudoUser sudoCommand
5. Client-Side sudo-ldap.conf Configuration
Configure each client to refer to LDAP-based sudo policies:
/etc/sudo-ldap.conf
base dc=example,dc=com
uri ldap://ldap.example.com
BINDDN cn=manager,dc=example,dc=com
BINDPW <manager_password>
SUDOERS_BASE ou=sudo,ou=people,dc=example,dc=com
Add to /etc/nsswitch.conf:
sudoers: files ldap
6. Index Optimization (Performance)
If logs repeatedly show messages such as:
bdb_equality_candidates: (sudoUser) not indexed
add indexes to improve performance.
Create /etc/openldap/ldif/index_sudo.ldif:
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: sudoUser eq,sub
olcDbIndex: sudoHost eq
Apply:
# ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/openldap/ldif/index_sudo.ldif
7. Centralized Logging with auditd + rsyslog
To track sudo/su command history in an LDAP environment, configure auditd and rsyslog.
7.1 auditd Configuration
Add the following to /etc/audit/audit.rules:
-w /etc/sudoers -p wa -k sudo_changes
-w /usr/bin/sudo -p x -k sudo_exec
-w /bin/su -p x -k su_exec
Apply:
# systemctl restart auditd
7.2 rsyslog Configuration
Forward LDAP and sudo logs to the central log server.
Create /etc/rsyslog.d/ldap.conf:
local4.* @@log.example.com:514
Apply:
# systemctl restart rsyslog
All sudo/su activities will be collected in /var/log/ldap.log on the central server.
8. Audit Log Example
type=USER_AUTH msg=audit(...): user pid=24123 uid=2001 auid=2001 ses=1439 msg='op=PAM:authentication acct="opsuser" exe="/usr/bin/sudo" res=success'
type=SYSCALL msg=audit(...): exe="/usr/bin/sudo" key="SEC_AUDIT" cwd="/home/opsuser" comm="systemctl" name="nginx" nametype=EXECVE
You can trace who (opsuser), when (timestamp), and what command (systemctl restart nginx) was executed.
9. Testing
- Log in as an LDAP account in the operations group (
%ops) - Run
sudo -lto verify policy retrieval from LDAP - Execute a command (e.g.,
sudo systemctl restart nginx) - Confirm the command history is logged on the central log server
10. Conclusion
| Feature | Description |
|---|---|
| Centralized sudo management | Unified control of all sudo privileges via LDAP |
| Policy migration | Automatically convert /etc/sudoers using sudoers2ldif |
| Command audit logging | Collect execution logs via auditd + rsyslog |
| Security reinforcement | Enforce role-based sudo policies for operations/development teams |
ⓒ 2025 엉뚱한 녀석의 블로그 [quirky guy's Blog]. All rights reserved. Unauthorized copying or redistribution of the text and images is prohibited. When sharing, please include the original source link.
🛠 마지막 수정일: 2025.10.22
답글 남기기
댓글을 달기 위해서는 로그인해야합니다.