최근 사내에서 EOS 작업으로 사용하고있는 Linux2에서 Linux2023으로 버전업을 진행했습니다.
이번에 담당하게 된 서버는 OpenLDAP + phpLDAPadmin으로 사내 계정을 관리하는 서버였는데요, 겉보기엔 데이터 용량도 작고(14MB!) 별거 아닌 것 같았는데 막상 진행해보니 생각보다 여러 고비를 넘겨야 했던 작업이라 기록으로 남겨봅니다.
작업 개요
- 기존: Amazon Linux 2, OpenLDAP(slapd) + phpLDAPadmin(PHP 5.4) + Apache
- 목표: Amazon Linux 2023 신규 EC2에 Docker 컨테이너로 동일 환경 재현
- 이관 방식: 데이터/설정 압축 → S3 업로드 → 신규 서버에서 다운로드 후 압축 해제 → Docker 컨테이너로 기동
PHP 5.4는 이미 한참 전에 EOL된 버전이라 AL2023 저장소에는 아예 패키지가 없더라고요. 그래서 고민 끝에 Amazon Linux 2 베이스 이미지로 Docker 컨테이너를 만들어서, 기존 환경을 그대로 재현하는 방식으로 갔습니다. 구조를 바꾸는 것보다, 일단 EOS 대응이 급선무였기 때문에 "돌아가던 걸 그대로 옮기자"는 방향으로 정했어요.
1. 데이터 백업 및 이관
LDAP 데이터는 생각보다 작았습니다 (14MB). 정합성을 위해 slapd를 정상 종료한 뒤 압축했어요.
sudo systemctl stop slapd
sudo tar -czvf ldap-migration.tar.gz \
/var/lib/ldap \
/etc/openldap \
/usr/share/phpldapadmin \
/etc/phpldapadmin \
/etc/httpd/conf.d/phpldapadmin.conf
sudo systemctl start slapd
S3로 업로드하고, 신규 서버에서 다운로드 후 압축 해제. 여기까지는 순조로웠습니다.
2. 근데 압축 풀다가 디스크가 꽉 찼다
tar: sonatype-work/nexus3/cache: Cannot mkdir: No space left on device
응? 데이터 용량이 크지도 않은데 왜 공간이 없지 싶었는데, 알고 보니 다운로드 받은 경로가 /tmp였고, 이 서버의 /tmp가 tmpfs(메모리 기반 파일시스템) 로 잡혀있었던 거였어요. 압축을 풀려는 대상이 훨씬 큰 다른 작업(같은 날 진행했던 Nexus 서버 이관)이랑 겹쳐서 헷갈렸던 부분도 있는데, 결론은 다운로드/압축해제 경로는 tmpfs가 아니라 실제 디스크 파티션인지 꼭 확인해야 한다는 교훈을 얻었습니다.
df -h
로 확인해보고, 디스크 기반 경로로 옮기거나, 필요하면 EBS 볼륨을 늘리고 파티션을 확장(growpart, xfs_growfs)해서 해결했습니다.
3. Docker 컨테이너는 만들었는데 slapd가 계속 죽는다
WARN exited: slapd (exit status 1; not expected)
...
gave up: slapd entered FATAL state, too many start retries too quickly
supervisord로 httpd와 slapd를 같이 띄우는 구조로 갔는데, httpd는 잘 뜨는데 slapd만 계속 재시작하다 죽어버리더라고요. 직접 포그라운드로 실행해서 로그를 보니 원인이 나왔습니다.
ldif_read_file: Permission denied for "/etc/openldap/slapd.d/cn=config.ldif"
호스트에서 볼륨 마운트한 설정 파일의 소유권이 안 맞았던 것이었어요. 컨테이너 안의 ldap 계정 UID/GID를 확인해서(id ldap), 호스트 쪽 데이터 폴더 권한을 거기에 맞춰주니 바로 해결됐습니다.
docker compose exec ldap id ldap
# uid=55(ldap) gid=55(ldap)
sudo chown -R 55:55 ./data/etc/openldap
sudo chown -R 55:55 ./data/var/lib/ldap
4. phpLDAPadmin은 뜨는데 403
Apache가 뜨긴 떴는데 curl로 확인해보니 403 Forbidden. 원인은 Apache 2.2 문법과 2.4 문법 차이였습니다.
# 이건 2.2 문법 (2.4에서는 씹힘)
Order Deny,Allow
Allow from all
# 2.4 문법으로 교체
Require all granted
기존 서버는 httpd 2.2 계열이었는데, 새로 만든 컨테이너의 yum 저장소에서 설치된 httpd는 2.4였던 게 원인이었어요. 옛날 설정 파일을 그대로 복사해오면서 생긴 버전 갭이었습니다.
5. ALB 헬스체크가 계속 Unhealthy
이건 애플리케이션 문제가 아니라 인프라 설정 문제였습니다.
- 헬스체크 경로 문제: 기본 경로 /로 체크하고 있었는데, 이 경로는 Apache 기본 테스트 페이지라 403이 남 → 헬스체크 경로를 실제 서비스 경로(/phpldapadmin/)로 변경
- 보안그룹 문제: 신규 서버 보안그룹에 ALB로부터의 인바운드 허용 규칙이 없었음 → ALB의 보안그룹을 신규 서버 보안그룹의 인바운드 소스로 추가
이 부분에서 삽질을 좀 했는데, curl -v로 로컬에서 직접 확인해보고 "로컬에서는 되는데 외부에서만 안 된다"는 걸 파악한 게 실마리가 됐습니다. 로컬에서 잘 되면 애플리케이션 문제가 아니라 네트워크/인프라 문제일 확률이 높더라고요.
6. 설정 파일 하나 권한 때문에 또 막힘
Missing configuration file /etc/phpldapadmin/config.php - have you created it?
파일은 분명히 있는데 이 에러가 계속 떴습니다. 확인해보니 권한이 640(소유자만 읽기 가능)으로 되어 있어서, Apache 실행 계정이 파일을 못 읽고 있었던 거예요.
chmod 644 /etc/phpldapadmin/config.php
7. 진짜 어려웠던 부분: SASL 인증 위임
여기까지 해결하고 웹 UI 로그인까지는 됐는데, 실제 연동된 서비스(GitLab)에서 LDAP 로그인을 시도하니 계속 인증 실패가 났습니다.
Could not authenticate you from Ldapmain because "Invalid credentials for OOO".
계정도 있고, 필터 조건도 맞는데 왜 계속 실패하나 싶어서 실제 저장된 값을 까봤더니:
userPassword:: {SASL}user@domain.com
{SASL} 방식으로 저장되어 있었습니다. 이게 뭐냐면, 이 LDAP 서버는 사용자 정보만 갖고 있고, 실제 비밀번호 인증은 외부 AD 서버로 위임하는 구조였던 거예요. 로컬 LDAP에는 애초에 비밀번호가 없으니, 아무리 맞는 비밀번호를 넣어도 로컬에서는 인증될 수가 없는 구조였습니다.
기존 서버를 다시 뒤져보니, 이 위임이 이루어지는 체인이 이렇게 구성되어 있었어요.
애플리케이션 → slapd (bind 요청)
↓ (설정: pwcheck_method: saslauthd)
saslauthd 데몬
↓ (유닉스 소켓 통신)
외부 AD 서버
즉, 데이터랑 slapd 설정만 옮기면 끝나는 게 아니라 saslauthd 데몬 자체와, 그 연동 설정 파일들까지 통째로 옮겨야 했던 거죠. 이 부분은 처음 백업 대상에 아예 포함을 안 했어서, 뒤늦게 추가로 확인하고 옮겼습니다.
RUN yum install -y cyrus-sasl cyrus-sasl-ldap
COPY etc/saslauthd.conf /etc/saslauthd.conf
COPY usr/lib64/sasl2/slapd.conf /usr/lib64/sasl2/slapd.conf
supervisord에도 saslauthd 프로세스를 추가해서 slapd, httpd와 함께 띄우도록 구성하고 나서야 최종적으로 정상 로그인이 되었습니다.
마무리하며
작은 서버라 금방 끝날 줄 알았는데, 막상 해보니 아래처럼 생각보다 다양한 계층에서 문제가 터졌습니다.
- 인프라(디스크, 보안그룹, ALB 헬스체크)
- OS/버전 차이(Apache 2.2 vs 2.4 문법)
- 파일 권한
- 인증 아키텍처 자체에 대한 이해 부족(SASL 위임 구조)
특히 마지막 SASL 부분은, 단순히 "데이터를 옮긴다"는 개념만 갖고 접근했다면 절대 못 풀었을 문제였어요. 이관 작업은 데이터만 옮기는 게 아니라, 그 데이터가 어떻게 쓰이는지(인증 흐름 전체)를 이해하고 옮겨야 한다는 걸 다시 한번 느꼈습니다.
이후에 이 LDAP을 사용하는 다른 서비스들(Rundeck, Redmine, Nexus, Grafana 등)도 하나씩 확인하면서 연결 정보를 갱신했는데, 이 얘기는 다음 포스팅에서 이어서 써보겠습니다.
'AWS' 카테고리의 다른 글
| CloudTrail 원인 추적, 액세스 키 비활성화 트러블슈팅 (0) | 2026.07.16 |
|---|---|
| EOS 대응, OpenLDAP을 Linux2에서 LINUX2023으로 서버 이관 #2 (1) | 2026.07.14 |
| Amazon Linux 2 EOS 대응 마이그레이션 후 Rundeck 인증 실패 트러블슈팅 (0) | 2026.07.09 |
| AWS SDK 버전 충돌 (0) | 2025.04.05 |
| AWS EC2 인스턴스에 ES 설치 후 ELB, ROUTE53 적용 하기 (0) | 2022.07.15 |
