⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

LDAP 인증 연동 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 11. 26. · 7 Views

LDAP 인증 연동 완벽 가이드

LDAP을 활용한 중앙 집중식 인증 시스템 구축 방법을 알아봅니다. OpenLDAP 설정부터 Postfix, Dovecot 연동, 그리고 Active Directory 통합까지 실무에서 바로 적용할 수 있는 내용을 다룹니다.


목차

  1. LDAP_기본_개념_및_구조
  2. OpenLDAP_컨테이너_설정
  3. Postfix_LDAP_연동_설정
  4. Dovecot_LDAP_인증_설정
  5. 그룹_기반_메일링_리스트
  6. Active_Directory_연동

1. LDAP 기본 개념 및 구조

어느 날 김개발 씨가 새로운 프로젝트에 투입되었습니다. 회사에서 사용하는 수십 개의 시스템마다 각각 로그인해야 하는 불편함을 해결해달라는 요청이었습니다.

"하나의 계정으로 모든 시스템에 로그인할 수 있으면 좋겠는데..." 선배 박시니어 씨가 힌트를 주었습니다. "LDAP을 한번 알아보세요."

LDAP은 Lightweight Directory Access Protocol의 약자로, 네트워크 상에서 디렉터리 서비스에 접근하기 위한 프로토콜입니다. 마치 거대한 전화번호부처럼 사용자 정보, 조직 구조, 인증 정보를 계층적으로 저장하고 빠르게 검색할 수 있습니다.

이를 통해 중앙에서 사용자를 관리하고, 여러 시스템이 동일한 인증 정보를 공유할 수 있습니다.

다음 코드를 살펴봅시다.

# LDAP 디렉터리 구조 예시 (LDIF 형식)
# DN(Distinguished Name)은 각 항목의 고유 경로입니다
dn: dc=example,dc=com
objectClass: organization
o: Example Company

# 조직 단위(OU) 정의
dn: ou=users,dc=example,dc=com
objectClass: organizationalUnit
ou: users

# 사용자 항목 정의
dn: uid=kimdev,ou=users,dc=example,dc=com
objectClass: inetOrgPerson
uid: kimdev
cn: Kim Developer
sn: Kim
mail: kimdev@example.com
userPassword: {SSHA}암호화된_비밀번호

김개발 씨는 입사 3개월 차 주니어 개발자입니다. 회사에서 사용하는 시스템이 너무 많았습니다.

이메일 시스템, 사내 위키, 버전 관리 시스템, 클라우드 서비스까지. 매번 다른 아이디와 비밀번호를 입력해야 했고, 새 직원이 입사하면 각 시스템마다 일일이 계정을 만들어줘야 했습니다.

선배 개발자 박시니어 씨가 커피를 건네며 말했습니다. "우리 회사도 예전엔 그랬어요.

그런데 LDAP을 도입하고 나서 세상이 달라졌죠." 그렇다면 LDAP이란 정확히 무엇일까요? 쉽게 비유하자면, LDAP은 마치 도서관의 중앙 카탈로그 시스템과 같습니다.

도서관에서 책을 찾을 때 카탈로그를 검색하면 어느 서가 몇 번째 칸에 있는지 바로 알 수 있죠. LDAP도 마찬가지로 사용자가 누구인지, 어떤 부서에 속해 있는지, 어떤 권한을 가지고 있는지 빠르게 찾아줍니다.

LDAP이 없던 시절에는 어땠을까요? 각 시스템마다 사용자 데이터베이스를 따로 관리해야 했습니다.

직원이 100명인 회사에서 10개의 시스템을 운영한다면, 이론적으로 1000개의 계정을 관리해야 하는 셈입니다. 비밀번호를 변경하려면 10번을 바꿔야 했고, 퇴사자가 생기면 10개 시스템에서 일일이 계정을 삭제해야 했습니다.

바로 이런 문제를 해결하기 위해 LDAP이 등장했습니다. LDAP의 핵심은 계층적 구조입니다.

마치 파일 시스템의 폴더 구조처럼, 최상위에 도메인이 있고 그 아래 조직 단위(OU)가 있으며, 각 OU 안에 사용자나 그룹이 존재합니다. 이 구조 덕분에 대규모 조직에서도 효율적으로 정보를 관리할 수 있습니다.

위의 코드를 살펴보겠습니다. 먼저 dc=example,dc=com은 도메인 컴포넌트로, 최상위 노드를 나타냅니다.

example.com이라는 도메인을 LDAP 형식으로 표현한 것입니다. 그 아래 ou=users는 사용자들을 담는 조직 단위입니다.

마지막으로 uid=kimdev는 실제 사용자 항목으로, 이메일, 이름, 비밀번호 등의 속성을 가집니다. **DN(Distinguished Name)**은 LDAP에서 가장 중요한 개념입니다.

각 항목의 고유한 경로를 나타내며, 파일 시스템의 절대 경로와 비슷합니다. uid=kimdev,ou=users,dc=example,dc=com은 김개발 씨의 고유 식별자가 됩니다.

실제 현업에서는 어떻게 활용할까요? 대기업에서는 수천 명의 직원 정보를 LDAP으로 관리합니다.

신입사원이 입사하면 LDAP에 한 번만 등록하면 되고, 연동된 모든 시스템에서 자동으로 로그인이 가능해집니다. 퇴사 시에도 LDAP에서 삭제하면 모든 접근 권한이 한 번에 차단됩니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 DN 경로를 잘못 작성하는 것입니다.

대소문자는 구분하지 않지만, 콤마 뒤의 공백이나 철자 오류는 인증 실패로 이어집니다. 따라서 DN을 작성할 때는 항상 정확한 형식을 확인해야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, 그래서 회사 시스템들이 하나의 계정으로 로그인되는 거였군요!" LDAP을 제대로 이해하면 중앙 집중식 인증 시스템을 구축할 수 있고, 이는 보안과 관리 효율성 모두를 높여줍니다.

실전 팁

💡 - DN은 아래에서 위로 읽으면 계층 구조를 이해하기 쉽습니다

  • LDAP 포트는 389(일반), 636(SSL/TLS)을 사용합니다
  • objectClass는 해당 항목이 어떤 속성을 가질 수 있는지 정의합니다

2. OpenLDAP 컨테이너 설정

김개발 씨는 LDAP 개념을 이해했지만, 막상 서버를 구축하려니 막막했습니다. 운영 서버에 직접 설치하기엔 부담스럽고, 테스트 환경이 필요했습니다.

박시니어 씨가 조언했습니다. "Docker로 OpenLDAP 컨테이너를 띄워보세요.

실습하기도 좋고, 나중에 운영 환경에도 그대로 쓸 수 있어요."

OpenLDAP은 가장 널리 사용되는 오픈소스 LDAP 서버입니다. Docker 컨테이너로 실행하면 복잡한 설치 과정 없이 빠르게 LDAP 서버를 구축할 수 있습니다.

osixia/openldap 이미지는 환경 변수만으로 대부분의 설정을 완료할 수 있어 초보자에게 적합합니다.

다음 코드를 살펴봅시다.

# docker-compose.yml
version: '3.8'
services:
  openldap:
    image: osixia/openldap:1.5.0
    container_name: ldap-server
    environment:
      # 기본 도메인 설정
      LDAP_ORGANISATION: "Example Company"
      LDAP_DOMAIN: "example.com"
      LDAP_ADMIN_PASSWORD: "admin_secret_password"
      # TLS 비활성화 (테스트용)
      LDAP_TLS: "false"
    ports:
      - "389:389"   # LDAP 포트
      - "636:636"   # LDAPS 포트
    volumes:
      - ldap_data:/var/lib/ldap
      - ldap_config:/etc/ldap/slapd.d

volumes:
  ldap_data:
  ldap_config:

김개발 씨는 로컬 환경에서 LDAP 서버를 구축해보기로 했습니다. 하지만 OpenLDAP을 직접 설치하려니 의존성 패키지도 많고, 설정 파일도 복잡했습니다.

"이걸 언제 다 설정하지..." 박시니어 씨가 화면을 보더니 웃었습니다. "요즘 누가 직접 설치해요?

Docker 쓰세요. 5분이면 됩니다." 그렇다면 Docker로 OpenLDAP을 구축하는 방법을 알아볼까요?

쉽게 비유하자면, Docker 컨테이너는 마치 이사할 때 쓰는 포장 박스와 같습니다. 모든 물건이 박스 안에 정리되어 있어서, 어디로 옮기든 박스만 열면 바로 사용할 수 있죠.

OpenLDAP 컨테이너도 마찬가지로, 필요한 모든 것이 이미지 안에 포함되어 있습니다. osixia/openldap 이미지는 가장 인기 있는 OpenLDAP Docker 이미지입니다.

환경 변수만 설정하면 복잡한 설정 파일을 건드리지 않아도 됩니다. 이것이 Docker의 강력함입니다.

위의 docker-compose.yml 파일을 살펴보겠습니다. LDAP_ORGANISATION은 조직 이름을 설정합니다.

이 값은 LDAP 디렉터리의 최상위 항목에 표시됩니다. LDAP_DOMAIN은 example.com으로 설정했는데, 이것이 dc=example,dc=com으로 변환됩니다.

LDAP_ADMIN_PASSWORD는 관리자 계정(cn=admin,dc=example,dc=com)의 비밀번호입니다. 테스트 환경이라도 복잡한 비밀번호를 사용하는 습관을 들이는 것이 좋습니다.

포트 설정도 중요합니다. 389번 포트는 일반 LDAP 통신에 사용되고, 636번 포트는 SSL/TLS로 암호화된 LDAPS 통신에 사용됩니다.

운영 환경에서는 반드시 636번 포트를 사용해야 합니다. volumes 섹션은 데이터 영구 보존을 위한 것입니다.

컨테이너를 삭제해도 ldap_data와 ldap_config 볼륨에 저장된 데이터는 유지됩니다. 이 설정이 없으면 컨테이너를 재시작할 때마다 모든 데이터가 사라집니다.

컨테이너를 실행하려면 터미널에서 docker-compose up -d 명령을 입력하면 됩니다. 몇 초 후 LDAP 서버가 준비됩니다.

실제로 잘 동작하는지 확인해볼까요? ldapsearch 명령으로 테스트할 수 있습니다.

docker exec ldap-server ldapsearch -x -H ldap://localhost -b dc=example,dc=com -D "cn=admin,dc=example,dc=com" -w admin_secret_password 명령을 실행하면 현재 디렉터리 내용이 출력됩니다. 하지만 주의할 점도 있습니다.

테스트 환경에서 LDAP_TLS를 false로 설정했지만, 운영 환경에서는 절대 이렇게 하면 안 됩니다. 비밀번호가 평문으로 전송되어 보안에 취약해집니다.

운영 환경에서는 반드시 인증서를 설정하고 TLS를 활성화해야 합니다. 김개발 씨는 docker-compose up -d 명령 하나로 LDAP 서버가 실행되는 것을 보고 감탄했습니다.

"정말 5분도 안 걸렸네요!" 이제 기본적인 LDAP 서버가 준비되었습니다. 다음은 이 서버에 메일 시스템을 연동하는 방법을 알아보겠습니다.

실전 팁

💡 - docker logs ldap-server 명령으로 컨테이너 로그를 확인할 수 있습니다

  • phpLDAPadmin 컨테이너를 추가하면 웹 UI로 LDAP을 관리할 수 있습니다
  • 운영 환경에서는 반드시 TLS 인증서를 설정하세요

3. Postfix LDAP 연동 설정

LDAP 서버 구축을 마친 김개발 씨에게 새로운 미션이 주어졌습니다. 회사 메일 서버인 Postfix가 LDAP의 사용자 정보를 참조하도록 연동해달라는 것이었습니다.

"메일 서버랑 LDAP이랑 어떻게 연결하죠?" 박시니어 씨가 Postfix 설정 파일을 열며 설명을 시작했습니다.

Postfix는 가장 널리 사용되는 오픈소스 메일 전송 에이전트(MTA)입니다. LDAP과 연동하면 사용자 메일 주소 검증, 가상 도메인 관리, 메일 별칭 처리를 중앙에서 관리할 수 있습니다.

Postfix는 LDAP 조회 테이블을 통해 실시간으로 사용자 정보를 확인합니다.

다음 코드를 살펴봅시다.

# /etc/postfix/ldap-users.cf
# LDAP 서버 연결 설정
server_host = ldap://localhost:389
search_base = ou=users,dc=example,dc=com
version = 3

# 바인딩 계정 (읽기 전용 권한 권장)
bind = yes
bind_dn = cn=readonly,dc=example,dc=com
bind_pw = readonly_password

# 메일 주소로 사용자 검색
query_filter = (mail=%s)
result_attribute = uid

# /etc/postfix/main.cf에 추가
# virtual_mailbox_maps = ldap:/etc/postfix/ldap-users.cf

김개발 씨는 메일 서버 담당자로부터 요청을 받았습니다. 현재 메일 서버는 사용자 목록을 별도 파일로 관리하고 있는데, 신규 입사자가 생길 때마다 수동으로 추가해야 하는 번거로움이 있었습니다.

"LDAP에 사용자 정보가 있으니까, 메일 서버가 거기서 직접 확인하면 되지 않을까요?" 박시니어 씨가 고개를 끄덕였습니다. "맞아요.

Postfix는 LDAP 조회 기능을 기본으로 지원해요." Postfix와 LDAP 연동은 어떻게 동작할까요? 쉽게 비유하자면, Postfix가 우체국이라면 LDAP은 주민등록 시스템입니다.

편지가 도착하면 우체국은 "이 사람이 정말 이 주소에 사는 게 맞나?" 하고 주민등록 시스템에 확인합니다. 등록된 사람이면 편지를 전달하고, 아니면 반송합니다.

위의 설정 파일을 자세히 살펴보겠습니다. server_host는 LDAP 서버 주소입니다.

같은 서버에 있다면 localhost를, 다른 서버에 있다면 해당 IP나 도메인을 입력합니다. 운영 환경에서는 ldaps://로 시작하는 보안 연결을 사용해야 합니다.

search_base는 검색을 시작할 위치입니다. ou=users,dc=example,dc=com으로 설정하면 users 조직 단위 아래에서만 검색합니다.

전체 디렉터리를 검색하려면 dc=example,dc=com으로 설정할 수 있지만, 성능상 범위를 좁히는 것이 좋습니다. bind_dnbind_pw는 LDAP에 연결할 때 사용할 계정 정보입니다.

여기서 중요한 점은 관리자 계정 대신 읽기 전용 계정을 사용하는 것입니다. Postfix는 사용자 정보를 읽기만 하면 되므로, 최소 권한 원칙에 따라 제한된 권한의 계정을 사용합니다.

query_filter는 핵심 설정입니다. (mail=%s)에서 %s는 Postfix가 검증하려는 메일 주소로 대체됩니다.

예를 들어 kimdev@example.com으로 메일이 오면 (mail=kimdev@example.com) 필터로 LDAP을 검색합니다. result_attribute는 검색 결과에서 어떤 속성을 반환할지 지정합니다.

uid를 반환하면 Postfix는 해당 사용자의 메일함 경로를 결정할 수 있습니다. 설정을 적용하려면 main.cf 파일에 virtual_mailbox_maps 설정을 추가해야 합니다.

이 설정은 Postfix에게 "가상 메일함 정보는 이 LDAP 설정 파일을 참조하라"고 알려줍니다. 설정을 변경한 후에는 postmap 명령으로 설정을 확인하고, postfix reload로 적용합니다.

postmap -q kimdev@example.com ldap:/etc/postfix/ldap-users.cf 명령을 실행하면 LDAP 조회가 제대로 동작하는지 테스트할 수 있습니다. 하지만 주의할 점도 있습니다.

LDAP 서버에 장애가 발생하면 메일 수신에도 영향을 미칩니다. 따라서 운영 환경에서는 LDAP 서버 이중화를 고려해야 합니다.

server_host에 여러 서버를 공백으로 구분하여 나열하면 자동으로 페일오버됩니다. 김개발 씨는 테스트 메일을 보내보았습니다.

LDAP에 등록된 사용자에게는 정상 전달되고, 등록되지 않은 주소로는 반송되는 것을 확인했습니다. "이제 사용자 추가할 때 LDAP에만 등록하면 되겠네요!"

실전 팁

💡 - postmap -q 명령으로 LDAP 조회를 테스트할 수 있습니다

  • 읽기 전용 LDAP 계정을 별도로 생성하여 사용하세요
  • LDAP 서버 장애에 대비해 이중화를 고려하세요

4. Dovecot LDAP 인증 설정

메일 전송은 해결되었지만, 사용자들이 메일을 읽으려면 인증이 필요했습니다. 김개발 씨는 Dovecot 설정을 열어보았습니다.

"Postfix는 메일을 받아오는 거고, Dovecot은 사용자가 메일을 가져가는 건가요?" 박시니어 씨가 고개를 끄덕였습니다. "맞아요.

IMAP, POP3 인증을 LDAP으로 처리하면 돼요."

Dovecot은 IMAP과 POP3 프로토콜을 제공하는 메일 배달 에이전트(MDA)입니다. 사용자가 Outlook이나 Thunderbird 같은 메일 클라이언트로 접속할 때 인증을 담당합니다.

LDAP 연동을 통해 중앙에서 관리되는 계정으로 메일에 접근할 수 있습니다.

다음 코드를 살펴봅시다.

# /etc/dovecot/dovecot-ldap.conf.ext
# LDAP 서버 연결
hosts = localhost:389
ldap_version = 3
base = ou=users,dc=example,dc=com

# 바인딩 설정
dn = cn=readonly,dc=example,dc=com
dnpass = readonly_password

# 인증 바인딩 방식 (사용자 비밀번호로 직접 바인딩)
auth_bind = yes
auth_bind_userdn = uid=%u,ou=users,dc=example,dc=com

# 사용자 정보 조회
user_filter = (&(objectClass=inetOrgPerson)(uid=%u))
user_attrs = =home=/var/mail/%u, =uid=vmail, =gid=vmail

# 비밀번호 조회 (auth_bind=no 일 때 사용)
pass_filter = (&(objectClass=inetOrgPerson)(uid=%u))
pass_attrs = userPassword=password

김개발 씨는 Postfix 연동을 마치고 뿌듯해했습니다. 하지만 아직 끝이 아니었습니다.

메일이 서버에 도착해도 사용자가 읽으려면 IMAP이나 POP3로 접속해야 합니다. 그리고 그때마다 인증이 필요합니다.

"Dovecot도 LDAP 연동을 해야겠네요." Dovecot과 LDAP 연동은 어떻게 동작할까요? 쉽게 비유하자면, Dovecot은 우편함 관리인입니다.

사용자가 우편함을 열려고 하면 "신분증 보여주세요"라고 합니다. 그리고 그 신분증이 진짜인지 LDAP(주민등록 시스템)에 확인합니다.

확인이 되면 우편함을 열어주고, 아니면 거부합니다. 위의 설정 파일에서 가장 중요한 것은 auth_bind 설정입니다.

auth_bind = yes로 설정하면 Dovecot은 사용자가 입력한 비밀번호로 직접 LDAP에 바인딩을 시도합니다. 바인딩이 성공하면 인증 성공, 실패하면 인증 실패입니다.

이 방식은 Dovecot이 사용자 비밀번호를 직접 다루지 않아도 되어 더 안전합니다. auth_bind_userdn은 사용자의 DN을 구성하는 템플릿입니다.

%u는 사용자가 입력한 사용자명으로 대체됩니다. 예를 들어 kimdev로 로그인하면 uid=kimdev,ou=users,dc=example,dc=com으로 바인딩을 시도합니다.

user_filter는 사용자 정보를 조회할 때 사용하는 필터입니다. objectClass=inetOrgPerson과 uid=%u 조건을 모두 만족하는 항목을 찾습니다.

이 필터로 메일함 경로 등 추가 정보를 가져옵니다. user_attrs는 LDAP 속성을 Dovecot 내부 변수로 매핑합니다.

=home=/var/mail/%u는 홈 디렉터리(메일함 경로)를 설정하고, =uid=vmail과 =gid=vmail은 파일 시스템 권한을 위한 UID/GID를 지정합니다. 만약 auth_bind = no로 설정한다면, Dovecot이 먼저 읽기 전용 계정으로 LDAP에 연결해서 사용자의 암호화된 비밀번호를 가져온 다음, 입력된 비밀번호와 비교합니다.

이 방식은 pass_filter와 pass_attrs 설정이 필요합니다. 설정을 적용하려면 dovecot.conf에서 passdb와 userdb를 LDAP으로 지정해야 합니다.

passdb { driver = ldap args = /etc/dovecot/dovecot-ldap.conf.ext }와 같이 설정합니다. 설정 후 doveadm auth test kimdev 명령으로 인증이 제대로 동작하는지 테스트할 수 있습니다.

하지만 주의할 점도 있습니다. auth_bind 방식을 사용할 때 사용자명 형식에 주의해야 합니다.

사용자가 kimdev@example.com 형식으로 로그인하면 %u에 전체 문자열이 들어가 DN이 잘못 구성됩니다. 이 경우 auth_username_format = %Ln 설정으로 @ 앞부분만 사용하도록 할 수 있습니다.

김개발 씨는 Thunderbird에서 IMAP 계정을 설정하고 로그인을 시도했습니다. LDAP 계정으로 로그인이 성공했고, 메일함이 열렸습니다.

"이제 하나의 계정으로 메일까지 쓸 수 있네요!"

실전 팁

💡 - doveadm auth test 명령으로 인증을 테스트하세요

  • auth_bind = yes가 보안상 더 권장됩니다
  • 로그인 실패 시 /var/log/dovecot.log를 확인하세요

5. 그룹 기반 메일링 리스트

개인 메일 인증은 완료되었지만, 팀장님에게서 새로운 요청이 들어왔습니다. "개발팀 전체에게 메일 보내려면 매번 10명 주소를 다 입력해야 하나요?

dev-team@example.com으로 보내면 팀원 전체에게 가면 안 될까요?" 김개발 씨는 LDAP 그룹 기능을 떠올렸습니다.

LDAP 그룹을 활용하면 메일링 리스트를 동적으로 관리할 수 있습니다. 그룹에 멤버를 추가하거나 제거하면 메일링 리스트도 자동으로 변경됩니다.

Postfix의 virtual_alias_maps를 LDAP 그룹과 연동하면 그룹 주소로 온 메일을 모든 멤버에게 전달할 수 있습니다.

다음 코드를 살펴봅시다.

# LDAP 그룹 항목 (LDIF)
dn: cn=dev-team,ou=groups,dc=example,dc=com
objectClass: groupOfNames
cn: dev-team
description: Development Team Mailing List
member: uid=kimdev,ou=users,dc=example,dc=com
member: uid=parksenior,ou=users,dc=example,dc=com
member: uid=leedesign,ou=users,dc=example,dc=com

# /etc/postfix/ldap-groups.cf
server_host = ldap://localhost:389
search_base = ou=groups,dc=example,dc=com
bind = yes
bind_dn = cn=readonly,dc=example,dc=com
bind_pw = readonly_password
# 그룹 이름으로 검색
query_filter = (cn=%u)
# 멤버들의 메일 주소 반환
result_attribute = member
special_result_attribute = member

김개발 씨는 팀장님의 요청을 받고 고민에 빠졌습니다. 메일링 리스트를 파일로 관리하면 팀원이 바뀔 때마다 수정해야 합니다.

하지만 LDAP 그룹을 사용하면? "LDAP에서 그룹 멤버를 관리하면, 메일링 리스트도 자동으로 동기화되지 않을까요?" 박시니어 씨가 웃으며 대답했습니다.

"바로 그거예요. LDAP 그룹과 Postfix를 연동하면 됩니다." LDAP 그룹 기반 메일링 리스트는 어떻게 동작할까요?

쉽게 비유하자면, LDAP 그룹은 마치 단체 카톡방 같습니다. 방에 사람을 추가하면 그 사람도 메시지를 받고, 나가면 더 이상 받지 않습니다.

LDAP 그룹에 멤버를 추가하면 그룹 메일을 받고, 제거하면 더 이상 받지 않습니다. 위의 LDIF 파일을 먼저 살펴보겠습니다.

groupOfNames는 그룹을 정의하는 objectClass입니다. cn=dev-team은 그룹의 이름이고, member 속성에 그룹에 속한 사용자들의 DN이 나열됩니다.

새 팀원이 오면 member 속성을 추가하고, 떠나면 제거하면 됩니다. 이제 Postfix 설정 파일인 ldap-groups.cf를 보겠습니다.

**query_filter = (cn=%u)**에서 %u는 @ 앞부분입니다. dev-team@example.com으로 메일이 오면 cn=dev-team인 그룹을 찾습니다.

result_attribute = member는 검색 결과에서 member 속성을 반환하라는 의미입니다. 이 속성에는 그룹 멤버들의 DN이 들어있습니다.

하지만 여기서 한 가지 문제가 있습니다. member 속성은 DN을 반환하는데, Postfix는 메일 주소가 필요합니다.

이를 해결하려면 추가 설정이 필요합니다. 한 가지 방법은 result_attribute를 mail로 변경하고, 그룹 멤버십에 mail 속성을 직접 저장하는 것입니다.

또 다른 방법은 Postfix의 ldap_expansion 기능을 사용하여 DN에서 메일 주소를 추가로 조회하는 것입니다. 실무에서는 posixGroup이나 groupOfUniqueNames 같은 다른 그룹 objectClass를 사용하기도 합니다.

각각 장단점이 있으니 조직의 요구사항에 맞게 선택합니다. main.cf에 virtual_alias_maps = ldap:/etc/postfix/ldap-groups.cf를 추가하면 그룹 메일링이 활성화됩니다.

기존 사용자 조회와 함께 사용하려면 콤마로 구분하여 여러 맵을 지정할 수 있습니다. 하지만 주의할 점도 있습니다.

그룹이 너무 커지면 LDAP 조회 성능에 영향을 줄 수 있습니다. 수백 명이 넘는 대규모 메일링 리스트는 별도의 메일링 리스트 관리자(Mailman 등)를 사용하는 것이 좋습니다.

또한 중첩 그룹(그룹 안의 그룹)은 별도 처리가 필요합니다. 김개발 씨는 dev-team@example.com으로 테스트 메일을 보냈습니다.

LDAP 그룹에 등록된 세 명 모두에게 메일이 도착했습니다. "팀원이 바뀌어도 LDAP에서만 관리하면 되겠네요!"

실전 팁

💡 - groupOfNames 대신 groupOfUniqueNames를 사용하면 중복 멤버를 방지할 수 있습니다

  • 대규모 그룹은 캐싱을 고려하세요
  • 중첩 그룹 지원이 필요하면 추가 설정이 필요합니다

6. Active Directory 연동

프로젝트가 성공적으로 마무리되자, 다른 부서에서도 관심을 보이기 시작했습니다. 하지만 본사에서는 이미 Windows Server의 Active Directory를 사용하고 있었습니다.

"OpenLDAP 대신 AD와 연동할 수는 없나요?" 김개발 씨는 새로운 도전 앞에 섰습니다.

**Active Directory(AD)**는 Microsoft의 디렉터리 서비스로, LDAP 프로토콜과 호환됩니다. 많은 기업에서 Windows 환경의 사용자 인증에 AD를 사용합니다.

기존 LDAP 연동 설정을 약간 수정하면 AD와도 연동할 수 있어, 별도의 OpenLDAP 서버 없이 중앙 인증을 구현할 수 있습니다.

다음 코드를 살펴봅시다.

# Active Directory 연동을 위한 Python 예제
import ldap3
from ldap3 import Server, Connection, ALL, NTLM

# AD 서버 연결 설정
AD_SERVER = 'ldap://ad.example.com:389'
AD_DOMAIN = 'EXAMPLE'
AD_BASE_DN = 'dc=example,dc=com'

def authenticate_ad_user(username, password):
    """Active Directory 사용자 인증"""
    server = Server(AD_SERVER, get_info=ALL)

    # NTLM 인증 방식 사용 (AD 권장)
    user_dn = f'{AD_DOMAIN}\\{username}'

    try:
        conn = Connection(
            server,
            user=user_dn,
            password=password,
            authentication=NTLM
        )
        if conn.bind():
            # 인증 성공 - 사용자 정보 조회
            conn.search(
                AD_BASE_DN,
                f'(sAMAccountName={username})',
                attributes=['cn', 'mail', 'memberOf']
            )
            return conn.entries[0] if conn.entries else None
    except Exception as e:
        print(f"Authentication failed: {e}")
    return None

김개발 씨는 본사 IT팀과 미팅을 했습니다. 본사에서는 이미 Active Directory로 수천 명의 직원을 관리하고 있었습니다.

Windows 로그인, 파일 서버 접근, 인트라넷 인증까지 모두 AD를 통해 이루어지고 있었습니다. "굳이 OpenLDAP을 새로 구축할 필요가 있을까요?

AD도 LDAP이잖아요." 박시니어 씨가 동의했습니다. "AD는 LDAP 프로토콜을 지원해요.

몇 가지 차이점만 알면 연동할 수 있습니다." Active Directory와 OpenLDAP의 차이점은 무엇일까요? 쉽게 비유하자면, 둘 다 전화번호부이지만 정리 방식이 조금 다릅니다.

OpenLDAP이 이름 순으로 정리된 전화번호부라면, AD는 부서별로 먼저 나누고 그 안에서 이름 순으로 정리된 전화번호부입니다. 기본 구조는 같지만 세부 속성 이름이 다릅니다.

가장 큰 차이는 사용자 식별 속성입니다. OpenLDAP에서는 uid를 사용하지만, AD에서는 sAMAccountName을 사용합니다.

또한 AD는 userPrincipalName(UPN) 형식(user@domain.com)도 지원합니다. 인증 방식도 다릅니다.

OpenLDAP은 단순 바인딩을 주로 사용하지만, AD는 NTLM이나 Kerberos 인증을 권장합니다. 위의 코드에서 authentication=NTLM으로 설정한 이유입니다.

위의 Python 코드를 살펴보겠습니다. ldap3 라이브러리를 사용합니다.

Python에서 LDAP 연동할 때 가장 많이 사용되는 라이브러리입니다. pip install ldap3로 설치할 수 있습니다.

**user_dn = f'{AD_DOMAIN}\{username}'**에서 DOMAIN\username 형식을 사용합니다. 이것이 AD의 전형적인 로그인 형식입니다.

NTLM 인증에서는 이 형식이 필수입니다. sAMAccountName 속성으로 사용자를 검색합니다.

OpenLDAP의 uid와 같은 역할을 합니다. memberOf 속성은 사용자가 속한 그룹 목록을 반환합니다.

Postfix나 Dovecot에서 AD와 연동할 때도 비슷한 수정이 필요합니다. query_filter에서 uid 대신 sAMAccountName을 사용하고, 바인딩 계정 형식을 AD 스타일로 변경합니다.

AD 연동 시 보안 그룹도 중요합니다. AD의 그룹은 memberOf 속성을 통해 확인할 수 있고, 이를 활용해 권한 기반 접근 제어를 구현할 수 있습니다.

하지만 주의할 점도 있습니다. AD는 기본적으로 389 포트로 평문 통신합니다.

운영 환경에서는 반드시 636 포트(LDAPS)나 StartTLS를 사용해야 합니다. 또한 AD의 비밀번호 정책이 엄격하여 계정 잠금이 발생할 수 있으니, 연동 테스트 시 주의가 필요합니다.

AD의 Global Catalog(GC) 포트(3268, 3269)를 사용하면 여러 도메인에 걸친 검색이 가능합니다. 대규모 조직에서는 이 포트를 활용하는 것이 효율적입니다.

김개발 씨는 본사 AD와 연동 테스트를 마쳤습니다. Windows 계정으로 메일 시스템에 로그인할 수 있게 되었습니다.

"이제 직원들이 하나의 비밀번호로 모든 시스템을 사용할 수 있겠네요!" LDAP을 제대로 이해하면 OpenLDAP이든 Active Directory든 유연하게 연동할 수 있습니다. 핵심 개념은 같고, 세부 구현만 다를 뿐입니다.

실전 팁

💡 - AD 연동 시 sAMAccountName과 userPrincipalName의 차이를 이해하세요

  • LDAPS(636) 또는 Global Catalog(3268/3269) 포트 사용을 권장합니다
  • 서비스 계정은 비밀번호 만료 없음으로 설정하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#LDAP#Authentication#OpenLDAP#ActiveDirectory#Postfix#Dovecot#LDAP,Authentication

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.