Ssoon

HashiCorp Vault - Auth with LDAP 본문

CICD Study [1기]

HashiCorp Vault - Auth with LDAP

구구달스 2025. 12. 7. 20:46

 

🔐 Vault LDAP Auth란

  • Vault는 다양한 Auth Method를 지원하며, 그 중 하나가 LDAP 기반 인증입니다. 
  • LDAP Auth Method를 사용하면, 기존에 사용 중인 LDAP 서버(예: 기업의 Active Directory 또는 OpenLDAP 등)의 사용자 계정과 비밀번호를 그대로 이용해 Vault에 로그인 할 수 있습니다. 이를 통해 Vault 전용 사용자 계정을 별도로 만들 필요가 없습니다. 
  • 즉, Vault + LDAP 연동을 통해 기존 사용자 디렉토리 체계를 활용하면서 Vault 접근 관리를 통합할 수 있습니다.

🧩 LDAP Auth Method의 동작과 구성 요소

▶️ 기본 동작

  • 사용자가 LDAP 계정(username/password)으로 Vault에 로그인 시도 (예: vault login -method=ldap username=...) 
  • Vault는 LDAP 서버에 bind 또는 search 과정을 통해 해당 사용자 인증을 수행
  • 인증이 성공하면 Vault가 토큰(token)을 발급. 이 토큰에 LDAP 계정에 매핑된 Vault policy가 붙게 됨 
  • 이후 Vault API 호출 시 이 토큰을 사용해 권한 제어(access control)를 진행

▶️ LDAP ↔ Vault 설정 항목

LDAP Auth를 사용하려면, Vault에 다음 항목들을 설정해야 합니다.

설정 항목 설명

url LDAP 서버 주소 — 예: ldap://ldap.example.com, ldaps://ldap.example.com:636 등. 여러 URL을 콤마로 나열하여 fail-over 가능. 
starttls true이면 unencrypted 연결 후 StartTLS 명령으로 TLS 보안 연결을 시작. 
insecure_tls true이면 LDAP 서버의 TLS 인증서를 검증하지 않음 — 테스트/실험 환경 전용, 운영에서는 권장 안됨. 
certificate (또는 OS trust store) LDAP 서버의 CA 인증서를 지정 — Vault ↔ LDAP 간 TLS 연결 시 필요. 운영 환경에서는 보통 CA 인증서를 지정하거나 OS trust store를 사용. 
binddn, bindpass LDAP directory tree 탐색(search) 또는 사용자 검색(bind)에 사용하는 계정 (예: "cn=vault,ou=Users,dc=example,dc=com") 및 비밀번호. 익명 bind 불가한 환경에서는 필수.
userdn 사용자 계정이 위치한 base DN — Vault가 로그인 시 검색을 수행할 위치.
userattr 로그인 시 사용자 이름(username)이 매핑될 LDAP attribute (예: sAMAccountName, uid, cn 등). 
groupdn, groupfilter, groupattr Vault policy 매핑을 위해, LDAP 그룹 멤버십을 찾아낼 설정. groupDN: 그룹이 위치한 base DN; groupFilter: LDAP search filter; groupAttr: 그룹 이름이 저장된 attribute. 
username_as_alias, max_page_size 등 사용자 alias 설정, 페이징된 LDAP 검색 제어 등 부가 옵션. 

🛠️ LDAP Auth 설정 예시

  • 아래는 LDAP 인증을 설정하고 사용하는 간단한 예시입니다.
# 1. LDAP auth method 활성화
vault auth enable ldap

# 2. LDAP 설정 (예: Active Directory or OpenLDAP)
vault write auth/ldap/config \
  url="ldap://ldap.example.com" \
  binddn="cn=vault-bind,ou=Users,dc=example,dc=com" \
  bindpass="vault-bind-password" \
  userdn="ou=Users,dc=example,dc=com" \
  userattr="sAMAccountName" \
  groupdn="ou=Groups,dc=example,dc=com" \
  groupfilter="(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={{.UserDN}}))" \
  groupattr="cn" \
  insecure_tls=false
  • 위 설정은 예시이며, LDAP 서버의 구조(DN, attribute, TLS 여부 등)에 맞게 조정해야 합니다.
  • 설정 후 LDAP 그룹 ↔ Vault policy 매핑이 필요합니다. 예:
vault write auth/ldap/groups/engineering policies=engineering-policy
  • 이후 LDAP 사용자로 로그인:
vault login -method=ldap username=john.doe
  • 성공 시 Vault 토큰이 발급되며, 해당 토큰에 매핑된 policy 권한을 갖게 됩니다. 

✅ LDAP Auth 사용 시 장점

  • 별도 Vault 사용자 디렉토리를 만들 필요 없이, 기존 LDAP 계정으로 인증 가능 — 사용자 관리 통합
  • 기업의 중앙 디렉토리(Active Directory, LDAP 등) 기반 권한 관리 + Vault policy 연동으로 접근 제어 간소화
  • 그룹 기반 접근 제어 용이 — LDAP 그룹 ↔ Vault policy 연결으로 역할 단위 권한 관리

⚠️ 주의사항 및 고려해야 할 점

  • LDAP 서버와 Vault 간 통신은 TLS (또는 StartTLS) 설정을 권장. 인증서 검증 무시(insecure_tls=true)는 보안 리스크가 있음. 
  • LDAP directory의 DN, attribute, group 구조가 Vault 설정과 맞아야 함 — 잘못된 설정 시 검색이나 그룹 매핑 실패 가능.
  • Vault 설정(config.hcl)만으로 LDAP Auth를 활성화할 수 없고, vault auth enable + vault write auth/ldap/config 등의 CLI/API 작업이 필요함. 
  • LDAP 서버 장애 또는 네트워크 문제 시 Vault 로그인 불가 → Vault 운영 환경에서는 가용성 고려 필요

✅실습

  • OpenLDAP 서버 배포
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: openldap
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: openldap
  namespace: openldap
spec:
  replicas: 1
  selector:
    matchLabels:
      app: openldap
  template:
    metadata:
      labels:
        app: openldap
    spec:
      containers:
        - name: openldap
          image: osixia/openldap:1.5.0
          ports:
            - containerPort: 389
              name: ldap
            - containerPort: 636
              name: ldaps
          env:
            - name: LDAP_ORGANISATION    # 기관명, LDAP 기본 정보 생성 시 사용
              value: "Example Org"
            - name: LDAP_DOMAIN          # LDAP 기본 Base DN 을 자동 생성
              value: "example.org"
            - name: LDAP_ADMIN_PASSWORD  # LDAP 관리자 패스워드
              value: "admin"
            - name: LDAP_CONFIG_PASSWORD
              value: "admin"
        - name: phpldapadmin
          image: osixia/phpldapadmin:0.9.0
          ports:
            - containerPort: 80
              name: phpldapadmin
          env:
            - name: PHPLDAPADMIN_HTTPS
              value: "false"
            - name: PHPLDAPADMIN_LDAP_HOSTS
              value: "openldap"   # LDAP hostname inside cluster
---
apiVersion: v1
kind: Service
metadata:
  name: openldap
  namespace: openldap
spec:
  selector:
    app: openldap
  ports:
    - name: phpldapadmin
      port: 80
      targetPort: 80
      nodePort: 30001
    - name: ldap
      port: 389
      targetPort: 389
    - name: ldaps
      port: 636
      targetPort: 636
  type: NodePort
EOF
namespace/openldap created
deployment.apps/openldap created
service/openldap created
  • 두 개의 조직 단위(Organizational Unit, OU) 엔트리를 OpenLDAP 서버에 추가
    • 사용된 관리자 계정: cn=admin,dc=example,dc=org
    • 추가된 엔트리:
      • ou=people,dc=example,dc=org
      • ou=groups,dc=example,dc=org
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl -n openldap exec -it deploy/openldap -c openldap -- bash
root@openldap-54857b746c-7dfxr:/# cat <<EOF | ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin
> dn: ou=people,dc=example,dc=org
> objectClass: organizationalUnit
> ou: people
>
> dn: ou=groups,dc=example,dc=org
> objectClass: organizationalUnit
> ou: groups
> EOF
adding new entry "ou=people,dc=example,dc=org"

adding new entry "ou=groups,dc=example,dc=org"
  •  OpenLDAP 서버에 두 명의 사용자(Alice와 Bob) 정보를 추가
root@openldap-54857b746c-7dfxr:/# cat <<EOF | ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin
> dn: uid=alice,ou=people,dc=example,dc=org
> objectClass: inetOrgPerson
> cn: Alice
> sn: Kim
e
mail: alice@ex> uid: alice
> mail: alice@example.org
> userPassword: alice123
>
> dn: uid=bob,ou=people,dc=example,dc=org
> objectClass: inetOrgPerson
> cn: Bob
> sn: Lee
> uid: bob
> mail: bob@example.org
> userPassword: bob123
> EOF
adding new entry "uid=alice,ou=people,dc=example,dc=org"

adding new entry "uid=bob,ou=people,dc=example,dc=org"
  • OpenLDAP 서버에 두 개의 새로운 그룹 엔트리를 추가하고, 이전에 생성했던 사용자인 Alice와 Bob을 각각의 그룹에 할당
root@openldap-54857b746c-7dfxr:/# cat <<EOF | ldapadd -x -D "cn=admin,dc=example,dc=org" -w admin
s
cn: devs
membe> dn: cn=devs,ou=groups,dc=example,dc=org
> objectClass: groupOfNames
> cn: devs
> member: uid=bob,ou=people,dc=example,dc=org
>
> dn: cn=admins,ou=groups,dc=example,dc=org
> objectClass: groupOfNames
> cn: admins
> member: uid=alice,ou=people,dc=example,dc=org
> EOF
adding new entry "cn=devs,ou=groups,dc=example,dc=org"

adding new entry "cn=admins,ou=groups,dc=example,dc=org"
  • Vault에 LDAP 인증 방법(Authentication Method) 을 활성화
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/learn-vault-secrets-operator/learn-vault-secrets-operator$ vault auth enable ldap
Success! Enabled ldap auth method at: ldap/
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/learn-vault-secrets-operator/learn-vault-secrets-operator$ vault auth list
Path                Type          Accessor                    Description                Version
----                ----          --------                    -----------                -------
demo-auth-mount/    kubernetes    auth_kubernetes_6132b7f8    n/a                        n/a
ldap/               ldap          auth_ldap_a66f2e61          n/a                        n/a
token/              token         auth_token_6bb8160d         token based credentials    n/a
  • Vault와 OpenLDAP 서버 간의 통신을 위한 LDAP 인증 백엔드 구성
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/learn-vault-secrets-operator/learn-vault-secrets-operator$ vault write auth/ldap/config \
    url="ldap://openldap.openldap.svc:389" \
    starttls=false \
    insecure_tls=true \
    binddn="cn=admin,dc=example,dc=org" \
    bindpass="admin" \
    userdn="ou=people,dc=example,dc=org" \
    groupdn="ou=groups,dc=example,dc=org" \
    groupfilter="(member=uid={{.Username}},ou=people,dc=example,dc=org)" \
    groupattr="cn"
Success! Data written to: auth/ldap/config
  • LDAP 사용자 Alice가 HashiCorp Vault에 성공적으로 로그인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault login -method=ldap username=alice
Password (will be hidden):
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                    Value
---                    -----
token                  hvs.CAESIKIRPpart1UlFhen7LjBJHD6YucXBjUR0lMsn1EBPAf9Gh4KHGh2cy5pRHcxMGl0amczZ1BuU3FRS3JnVFEwekU
token_accessor         g8lCH0LyuqdqbWlHEjQ2wDsp
token_duration         768h
token_renewable        true
token_policies         ["default"]
identity_policies      []
policies               ["default"]
token_meta_username    alice
  • LDAP 사용자 Alice가 로그인하여 발급받은 토큰정보
    • 토큰에 부여된 정책이 [default]만 있다는 것은, Alice가 속한 LDAP 그룹 (admins)에 Vault의 더 강력한 정책(예: admin 정책)이 아직 연결되지 않았다는 것을 다시 한번 확인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault token lookup
Key                 Value
---                 -----
accessor            g8lCH0LyuqdqbWlHEjQ2wDsp
creation_time       1765367061
creation_ttl        768h
display_name        ldap-alice
entity_id           b3762731-ebe3-aa60-bb74-7a4015a2cfbf
expire_time         2026-01-11T11:44:21.495085778Z
explicit_max_ttl    0s
id                  hvs.CAESIKIRPpart1UlFhen7LjBJHD6YucXBjUR0lMsn1EBPAf9Gh4KHGh2cy5pRHcxMGl0amczZ1BuU3FRS3JnVFEwekU
issue_time          2025-12-10T11:44:21.495089029Z
meta                map[username:alice]
num_uses            0
orphan              true
path                auth/ldap/login/alice
policies            [default]
renewable           true
ttl                 767h59m26s
type                service
  • 현재 활성화된 토큰이 LDAP 사용자 Bob의 토큰임을 확인합니다. Alice와 마찬가지로 Bob도 default 정책만 가지고 있어 관리자 작업을 할 수 없습니다.
  • 사용자가 Vault 초기 루트 토큰을 직접 입력하여 다시 로그인했습니다. 루트 토큰은 policies: ["root"]를 가지며, Vault의 모든 권한(무제한 권한)을 가집니다.
  • 루트 토큰으로 권한을 확보한 후, admin 정책을 성공적으로 Vault에 업로드했습니다. 이 정책은 path  sudo를 포함한 모든 권한을 부여하여 최상위 관리자 권한을 정의합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault policy write admin - <<EOF
path "*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
EOF
Error uploading policy: Error making API request.

URL: PUT http://localhost:30000/v1/sys/policies/acl/admin
Code: 403. Errors:

* 1 error occurred:
        * permission denied


(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault token lookup
Key                 Value
---                 -----
accessor            2n3PfoH76VCk8Yx04N2Pk5SS
creation_time       1765367183
creation_ttl        768h
display_name        ldap-bob
entity_id           1e7be4c1-c9ba-8f4d-63cd-7ae2218555c6
expire_time         2026-01-11T11:46:23.342050127Z
explicit_max_ttl    0s
id                  hvs.CAESIO33thb9EmtRQ_f9sp1QqtisHBJnyY3dVVlu5Yskn4uNGh4KHGh2cy5FVjNYYThQT0ZpajRRRnA2VnBFVHUwMTQ
issue_time          2025-12-10T11:46:23.342054857Z
meta                map[username:bob]
num_uses            0
orphan              true
path                auth/ldap/login/bob
policies            [default]
renewable           true
ttl                 767h58m11s
type                service
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault login
Token (will be hidden):
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                  Value
---                  -----
token                root
token_accessor       OUrn6HPnbM1vu9yICVceNt2i
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault policy write admin - <<EOF
path "*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
EOF
Success! Uploaded policy: admin

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault policy read admin
path "*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
  • 이전에 OpenLDAP에서 생성한 admins 그룹을 Vault의 admin 정책에 연결
    • admins 그룹의 멤버들은 Vault 로그인 시 admin 정책을 자동으로 부여
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault write auth/ldap/groups/admins policies=admin
Success! Data written to: auth/ldap/groups/admins
  • Alice가 LDAP 자격 증명으로 Vault에 다시 로그인하여 새로운 정책이 적용되었는지 확인
    • 이전에 default 정책만 가지고 있던 Alice는 이제 admins 그룹 멤버십을 통해 Vault의 강력한 admin 정책을 부여
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault login -method=ldap username=alice password=alice123
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                    Value
---                    -----
token                  hvs.CAESIJ7cZI2bTopszT1O8oJ75PIjFuXqC4n8-hI1ZL5LyHjZGh4KHGh2cy50U1J3RzhHa0hLSWU0MW5IOG1iY0ZOMXE
token_accessor         zggC8QulgkDODVVmWhVSNIqc
token_duration         768h
token_renewable        true
token_policies         ["admin" "default"]
identity_policies      []
policies               ["admin" "default"]
token_meta_username    alice
  • 현재 토큰 권한으로 admin 정책의 내용을 읽을 수 있는지 확인
    • Alice의 토큰이 admin 정책을 가지고 있기 때문에, 이 정책의 메타데이터(내용)를 읽을 수 있는 권한이 부여 (이전에는 default 정책만 있어 이 작업을 수행할 수 없었습니다.)
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ vault policy read admin
path "*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
Comments