운영에서 중요한 세 가지
LDAP 서버는 사내 모든 인증의 단일 지점입니다. LDAP이 내려가면 NAS, 그룹웨어, 파일 서버 모두 로그인이 안 됩니다. 운영에서 챙겨야 할 것은 세 가지입니다.
- 백업: 데이터가 날아가도 복구할 수 있어야 합니다
- 로그 관리: 디스크가 가득 차지 않도록 로그를 정리해야 합니다
- 모니터링: 서비스가 살아있는지 주기적으로 확인해야 합니다
백업 전략
무엇을 백업하는가
| 대상 | 경로 | 내용 |
|---|---|---|
| LDAP 데이터 (MDB) | /data/openldap/ | 실제 디렉토리 데이터 |
| slapd 설정 (OLC) | /data/ldap-config/ | cn=config 설정 |
| TLS 인증서 | /data/ldap-certs/ | CA·서버 인증서·키 |
이 세 가지를 모두 백업해야 완전한 복구가 가능합니다.
백업 보관 정책
| 주기 | 보관 기간 | 용도 |
|---|---|---|
| daily | 7일 | 최근 실수 복구 |
| weekly | 30일 | 중기 복구 |
| monthly | 365일 | 장기 보관 |
백업 스크립트
#!/bin/bash
# ldap-backup.sh
BACKUP_ROOT="/data/backup/ldap"
DAILY_DIR="$BACKUP_ROOT/daily"
WEEKLY_DIR="$BACKUP_ROOT/weekly"
MONTHLY_DIR="$BACKUP_ROOT/monthly"
DATE=$(date +%Y%m%d_%H%M%S)
DOW=$(date +%u) # 1=월 ~ 7=일
DOM=$(date +%d) # 01~31
mkdir -p $DAILY_DIR $WEEKLY_DIR $MONTHLY_DIR
# 1. LDAP 데이터 덤프 (slapcat으로 LDIF 추출)
LDIF_FILE="/tmp/ldap_backup_$DATE.ldif"
docker exec openldap slapcat -n 1 > $LDIF_FILE
# cn=config도 별도 덤프
CONFIG_FILE="/tmp/ldap_config_$DATE.ldif"
docker exec openldap slapcat -n 0 > $CONFIG_FILE
# 2. 인증서 포함하여 압축
BACKUP_FILE="$DAILY_DIR/ldap_$DATE.tar.gz"
tar -czf $BACKUP_FILE \
$LDIF_FILE \
$CONFIG_FILE \
/data/ldap-certs/
# 임시 파일 정리
rm -f $LDIF_FILE $CONFIG_FILE
echo "[$(date)] 백업 완료: $BACKUP_FILE ($(du -sh $BACKUP_FILE | cut -f1))"
# 3. weekly: 일요일마다
if [ "$DOW" = "7" ]; then
cp $BACKUP_FILE "$WEEKLY_DIR/ldap_weekly_$DATE.tar.gz"
fi
# 4. monthly: 매월 1일마다
if [ "$DOM" = "01" ]; then
cp $BACKUP_FILE "$MONTHLY_DIR/ldap_monthly_$DATE.tar.gz"
fi
# 5. 오래된 백업 삭제
find $DAILY_DIR -name "*.tar.gz" -mtime +7 -delete
find $WEEKLY_DIR -name "*.tar.gz" -mtime +30 -delete
find $MONTHLY_DIR -name "*.tar.gz" -mtime +365 -delete
echo "[$(date)] 정리 완료"
crontab 등록
crontab -e
# 매일 새벽 2시에 LDAP 백업
0 2 * * * /app/openldap/ldap-backup.sh >> /log/openldap/backup.log 2>&1
백업 복구
slapadd로 복구
# 서비스 중지
./ldapserver.sh stop
# 기존 데이터 초기화 (주의: 데이터 삭제)
sudo rm -rf /data/openldap/*
sudo rm -rf /data/ldap-config/*
# LDIF에서 복구
docker run --rm \
-v /data/openldap:/var/lib/ldap \
-v /data/ldap-config:/etc/ldap/slapd.d \
-v /tmp:/backup \
osixia/openldap:1.5.0 \
slapadd -n 1 -l /backup/ldap_backup.ldif
# 서비스 재시작
./ldapserver.sh start
대화형 복구 스크립트
백업 파일 목록을 보여주고 선택하면 자동 복구하는 스크립트를 만들어두면 편합니다.
#!/bin/bash
# ldap-restore.sh (대화형)
BACKUP_ROOT="/data/backup/ldap"
echo "=== LDAP 복구 스크립트 ==="
echo ""
echo "사용 가능한 백업:"
ls -lht $BACKUP_ROOT/daily/*.tar.gz 2>/dev/null | head -7
ls -lht $BACKUP_ROOT/weekly/*.tar.gz 2>/dev/null | head -4
echo ""
read -p "복구할 백업 파일 전체 경로: " BACKUP_FILE
if [ ! -f "$BACKUP_FILE" ]; then
echo "파일이 없습니다: $BACKUP_FILE"
exit 1
fi
echo ""
echo "경고: 현재 LDAP 데이터가 모두 삭제됩니다."
read -p "계속하시겠습니까? (yes/no): " CONFIRM
if [ "$CONFIRM" != "yes" ]; then
echo "취소되었습니다."
exit 0
fi
# 압축 해제
RESTORE_DIR="/tmp/ldap_restore_$(date +%s)"
mkdir -p $RESTORE_DIR
tar -xzf $BACKUP_FILE -C $RESTORE_DIR
# 서비스 중지
systemctl --user stop openldap.service
# 데이터 초기화
rm -rf /data/openldap/* /data/ldap-config/*
# 복구 실행
LDIF=$(find $RESTORE_DIR -name "ldap_backup_*.ldif" | head -1)
docker run --rm \
-v /data/openldap:/var/lib/ldap \
-v /data/ldap-config:/etc/ldap/slapd.d \
-v $RESTORE_DIR:/backup \
osixia/openldap:1.5.0 \
slapadd -n 1 -l /backup/$(basename $LDIF)
# 서비스 재시작
systemctl --user start openldap.service
rm -rf $RESTORE_DIR
echo "복구 완료."
로그 관리
slapd 로그 레벨
.env의 LDAP_LOG_LEVEL=256은 stats 레벨입니다.
연결·바인드·검색 통계가 기록되어 문제 추적에 유용합니다.
| 레벨 값 | 이름 | 내용 |
|---|---|---|
| 0 | 없음 | 로그 비활성화 |
| 256 | stats | 연결·바인드·검색 통계 |
| 512 | stats2 | 결과 통계 추가 |
| 4 | args | 모든 인수 |
| -1 | all | 전체 (디버깅용, 매우 상세) |
운영 환경에서는 256 또는 0을 권장합니다. -1은 디버깅 시에만 사용합니다.
logrotate 설정
로그를 방치하면 디스크가 금방 찹니다. logrotate로 자동 관리합니다.
# /etc/logrotate.d/openldap (또는 /app/openldap/openldap-logrotate.conf)
/log/openldap/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
docker exec openldap bash -c "kill -USR1 \$(cat /var/run/slapd/slapd.pid 2>/dev/null)" 2>/dev/null || true
endscript
}
/log/phpldapadmin/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
}
# logrotate 설정 적용
sudo cp openldap-logrotate.conf /etc/logrotate.d/openldap
# 즉시 테스트 (--debug로 실제 실행 없이 확인)
sudo logrotate --debug /etc/logrotate.d/openldap
# 강제 실행
sudo logrotate --force /etc/logrotate.d/openldap
헬스체크
즉시 확인 명령어
# 컨테이너 상태
docker inspect --format='{{.State.Status}}' openldap phpldapadmin
# LDAP 연결 테스트 (RootDSE 조회)
docker exec openldap ldapsearch -x \
-H ldap://localhost:389 \
-s base -b "" "(objectClass=*)" namingContexts
# 사용자 수 확인
docker exec openldap ldapsearch -x \
-H ldap://localhost:389 \
-D "cn=readonly,dc=ldap,dc=example,dc=com" \
-w 'readonly_password' \
-b "ou=people,dc=ldap,dc=example,dc=com" \
"(objectClass=posixAccount)" dn | grep -c "^dn:"
# 리소스 사용량
docker stats --no-stream openldap phpldapadmin
헬스체크 스크립트 (알림 연동)
#!/bin/bash
# ldap-healthcheck.sh
WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
LDAP_HOST="ldap://localhost:389"
LDAP_DN="cn=readonly,dc=ldap,dc=example,dc=com"
LDAP_PW="readonly_password"
BASE="dc=ldap,dc=example,dc=com"
alert() {
local msg="$1"
echo "[ALERT] $msg"
if [ -n "$WEBHOOK_URL" ]; then
curl -s -X POST -H 'Content-type: application/json' \
--data "{"text":"[LDAP 알림] $msg"}" \
"$WEBHOOK_URL" > /dev/null
fi
}
# 1. 컨테이너 상태
STATUS=$(docker inspect --format='{{.State.Status}}' openldap 2>/dev/null)
if [ "$STATUS" != "running" ]; then
alert "OpenLDAP 컨테이너 비정상: $STATUS"
exit 1
fi
# 2. LDAP 응답 확인
if ! docker exec openldap ldapsearch -x -H "$LDAP_HOST" \
-s base -b "" "(objectClass=*)" namingContexts > /dev/null 2>&1; then
alert "LDAP 응답 없음"
exit 1
fi
# 3. 사용자 수 확인
COUNT=$(docker exec openldap ldapsearch -x -H "$LDAP_HOST" \
-D "$LDAP_DN" -w "$LDAP_PW" \
-b "ou=people,$BASE" "(objectClass=posixAccount)" dn \
2>/dev/null | grep -c "^dn:")
if [ "$COUNT" -lt 1 ]; then
alert "사용자 수 이상: ${COUNT}명"
exit 1
fi
echo "[OK] LDAP 정상 — 사용자 ${COUNT}명"
# 5분마다 헬스체크
*/5 * * * * /app/openldap/ldap-healthcheck.sh >> /log/openldap/healthcheck.log 2>&1
systemd 자동 복구 설정
컨테이너가 비정상 종료되면 자동으로 재시작합니다.docker-compose.yml의 restart: unless-stopped로 Docker 수준 재시작은 이미 설정되어 있습니다.
systemd 서비스 파일에도 재시작 정책을 추가할 수 있습니다.
[Service]
Restart=on-failure
RestartSec=10
운영 체크리스트
| 주기 | 항목 | 방법 |
|---|---|---|
| 매일 | 백업 완료 여부 | /log/openldap/backup.log 확인 |
| 매일 | 디스크 사용량 | du -sh /data/openldap /log/openldap |
| 주간 | 로그 크기 | ls -lh /log/openldap/ |
| 주간 | 인증서 만료일 | openssl x509 -in /data/ldap-certs/ldap.crt -noout -dates |
| 월간 | 백업 복구 테스트 | 스테이징 환경에서 복구 시뮬레이션 |
| 연간 | 비밀번호 갱신 | 관리자·readonly 계정 비밀번호 순환 |
시리즈를 마치며
이 시리즈에서 다룬 내용을 돌아봅니다.
| 편 | 핵심 내용 |
|---|---|
| 00 | MS AD 대신 OpenLDAP을 선택한 이유, LDAP 표준 준수의 중요성 |
| 01 | Base DN 설계, flat 사용자 구조, 그룹 네이밍 전략 |
| 02 | Rootless Docker 설치, docker-compose, systemd user 서비스 |
| 03 | Self-Signed TLS 인증서 발급, LDAPS 설정 |
| 04 | customHRPerson·groupPosixAux 커스텀 스키마, STRUCTURAL 충돌 해결 |
| 05 | 사용자·그룹 LDIF 관리, Samba 연동, NT 해시 생성 |
| 06 | Synology NAS DSM LDAP 클라이언트 설정, 그룹 권한 매핑 |
| 07 | 백업 전략, logrotate, 헬스체크, 운영 자동화 |
LDAP은 한 번 잘 설계하고 표준을 지키면 Synology, Samba, 그룹웨어 어디에 붙여도 잘 동작합니다.
자유도가 높다는 것은 잘 쓰면 강력하고, 잘못 쓰면 기술 부채가 된다는 의미이기도 합니다.
이 시리즈가 OpenLDAP을 처음 구축하는 분들에게 실질적인 출발점이 되길 바랍니다.