OpenLDAP 기반 통합 인증 아키텍처 (4) — SUDO 권한 통합과 감사 로그 연동

1. 개요

이 문서는 OpenLDAP 서버에서 sudo 권한 정책을 중앙 집중화하고,
auditd + rsyslog 조합으로 명령 실행 이력을 중앙 로그 서버에 수집하는 방법을 다룬다.

특히, 기존 /etc/sudoers 파일을 LDAP 포맷으로 변환하기 위한 sudoers2ldif 스크립트 작성 및 실행 절차를 포함한다.
이를 통해 개별 서버의 sudoers 설정을 모두 제거하고, LDAP 상에서 일괄 관리가 가능해진다.

⚠️ 주의:
본문에 등장하는 IP, 계정명, 도메인명, hostname 등은 모두 예시이다.
실제 환경에서는 반드시 조직 보안 정책에 맞게 수정해야 한다.


2. 구성 개요

LDAP 기반 sudo 정책 통합은 다음과 같은 흐름으로 구성된다.

[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

각 클라이언트는 sudo 실행 시 LDAP 서버로부터 정책을 조회하며,
운영팀·개발팀별로 다른 sudo 권한이 적용된다.


3. SUDO 스키마 적용

LDAP 서버에서 sudoRole 오브젝트를 사용할 수 있도록 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

적용이 완료되면 sudoRole 오브젝트를 LDAP에 추가할 수 있다.


4. sudoers2ldif 스크립트 생성 및 LDIF 변환

4.1 스크립트 생성

배포판에 /usr/share/doc/sudo*/sudoers2ldif가 없는 경우,
직접 스크립트를 생성해야 한다.

# mkdir -p /usr/share/doc/sudo-custom
# vi /usr/share/doc/sudo-custom/sudoers2ldif

아래 내용을 그대로 붙여넣는다. (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

실행 권한 부여:

# chmod +x /usr/share/doc/sudo-custom/sudoers2ldif

4.2 변환 실행

# export SUDOERS_BASE="ou=sudo,ou=people,dc=example,dc=com"
# /usr/share/doc/sudo-custom/sudoers2ldif /etc/sudoers > /etc/openldap/ldif/sudoers.ldif

변환된 파일은 /etc/openldap/ldif/sudoers.ldif 에 생성된다.


4.3 변환 결과 예시

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 LDAP 서버에 반영

# ldapadd -x -W -D "cn=manager,dc=example,dc=com" -f /etc/openldap/ldif/sudoers.ldif

적용 확인:

# ldapsearch -x -LLL -b "ou=sudo,ou=people,dc=example,dc=com" cn sudoUser sudoCommand

5. 클라이언트 sudo-ldap.conf 설정

클라이언트가 LDAP 기반 sudo 정책을 참조하도록 설정한다.

/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

/etc/nsswitch.conf 에 다음 추가:

sudoers: files ldap

6. 인덱스 최적화 (성능 개선)

로그에 아래 메시지가 반복된다면 인덱스를 추가한다.

bdb_equality_candidates: (sudoUser) not indexed

LDIF 파일 생성 /etc/openldap/ldif/index_sudo.ldif:

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: sudoUser eq,sub
olcDbIndex: sudoHost eq

적용:

# ldapmodify -Y EXTERNAL -H ldapi:/// -f /etc/openldap/ldif/index_sudo.ldif

7. auditd + rsyslog 로그 통합

LDAP 인증 환경에서 sudo/su 명령 이력을 남기기 위해 auditd와 rsyslog를 구성한다.

7.1 auditd 설정

/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

적용:

# systemctl restart auditd

7.2 rsyslog 중앙 로그 전송

LDAP 및 sudo 로그를 중앙 서버로 전송한다.
/etc/rsyslog.d/ldap.conf 파일 작성:

local4.*   @@log.example.com:514

적용:

# systemctl restart rsyslog

중앙 서버의 /var/log/ldap.log 에 sudo/su 실행 기록이 적재된다.


8. 감사 로그 예시

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

누가(opsuser), 언제(timestamp), 어떤 명령(systemctl restart nginx)을 실행했는지 추적할 수 있다.


9. 테스트

  1. LDAP에 등록된 운영팀(%ops) 계정으로 로그인
  2. sudo -l 명령으로 LDAP 정책 확인
  3. 명령 실행 (sudo systemctl restart nginx)
  4. 중앙 로그 서버에 실행 이력(auditd)이 기록되는지 확인

10. 결론

이 구성을 통해 다음을 달성할 수 있다.

항목설명
sudo 중앙관리모든 sudo 권한을 LDAP에서 통합 제어
기존 정책 이관/etc/sudoers를 sudoers2ldif로 자동 변환
명령 이력 감사auditd + rsyslog로 명령 실행 로그 수집
보안 강화운영팀/개발팀별 sudo 제한 및 정책 일원화
ⓒ 2025 엉뚱한 녀석의 블로그 [quirky guy's Blog]. 본문 및 이미지를 무단 복제·배포할 수 없습니다. 공유 시 반드시 원문 링크를 명시해 주세요.
ⓒ 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