LDAP 인증 방식

LDAP 인증 방식

사용자 지정 GUI 로그인을 지원해요.

이 방식은 Vault Enterprise GUI 사용자의 기본 또는 백업 로그인 방식으로 선택될 수 있어요. 자세한 내용은 사용자 지정 로그인 옵션 관리 가이드를 참고하세요.

참고: 이 엔진은 TLS 또는 서명 검증의 일부로 외부 X.509 인증서를 사용할 수 있어요. SHA-1을 사용하는 X.509 인증서에 대한 서명 검증은 구식화(Deprecated)되었고 Vault 1.12부터 워크어라운드 없이는 더 이상 사용할 수 없어요. 자세한 내용은 구식화 공지를 참고하세요.

ldap 인증 방식은 기존 LDAP 서버와 사용자/비밀번호 크레덴셜을 사용한 인증을 허용해요. 이를 통해 LDAP를 사용하는 환경에 user/pass 구성을 여러 곳에 중복하지 않고 Vault를 통합할 수 있어요.

LDAP의 그룹과 사용자를 Vault 정책으로 매핑하는 것은 users/와 groups/ 경로를 사용해 관리돼요.

출처: 문서

본문

이스케이프에 관한 참고 사항 (A note on escaping)

관리자의 책임으로 올바르게 이스케이프된 DN을 제공하는 것이에요. 여기에는 사용자 DN, 검색을 위한 바인드 DN 등이 포함돼요.

이 방식이 수행하는 유일한 DN 이스케이프는 로그인 시 주어진 사용자 이름을 최종 바인드 DN에 삽입할 때이며, RFC 4514에 정의된 이스케이프 규칙을 사용해요.

또한 Active Directory는 RFC와 약간 다른 이스케이프 규칙을 가지고 있어요. 특히 DN의 위치와 무관하게 '#'의 이스케이프가 필요하고(RFC는 첫 번째 문자일 때만 필요), '='은 RFC가 백슬래시로 이스케이프할 수 있다고 나타내지만 필수 이스케이프 세트에는 포함되지 않아요. Active Directory를 사용하고 이러한 문자가 사용자 이름에 나타나면 구성된 DN에서 올바르게 이스케이프되는 것 외에도 이스케이프되도록 확인하세요.

참고로 RFC 4514와 Active Directory에서 이스케이프할 문자에 대한 이 TechNet 게시물을 보세요.

인증 (Authentication)

CLI를 통해 (Via the CLI)

$ vault login -method=ldap username=mitchellh
Password (will be hidden):
Successfully authenticated! The policies that are associated
with this token are listed below:

admins

API를 통해 (Via the API)

$ curl \
    --request POST \
    --data '{"password": "foo"}' \
    http://127.0.0.1:8200/v1/auth/ldap/login/mitchellh

응답은 JSON 형식이에요. 예:

{
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": null,
  "auth": {
    "client_token": "c4f280f6-fdb2-18eb-89d3-589e2e834cdb",
    "policies": [
      "admins"
    ],
    "metadata": {
      "username": "mitchellh"
    },
    "lease_duration": 0,
    "renewable": false
  }
}

구성 (Configuration)

인증 방식은 사용자나 머신이 인증하기 전에 미리 구성되어야 해요. 이 단계들은 보통 운영자나 설정 관리 도구가 수행해요.

1. ldap 인증 방식을 활성화합니다.

$ vault auth enable ldap

2. LDAP 서버에 대한 연결 세부 사항, 사용자 인증 방법, 그리고 그룹 멤버십 query 방법을 구성합니다. 구성 옵션은 아래에 분류되어 자세히 설명돼요.

연결 파라미터 (Connection parameters)

  • url (string, required) — 연결할 LDAP 서버. 예: ldap://ldap.myorg.com, ldaps://ldap.myorg.com:636. 쉼표로 구분된 URL 목록일 수도 있고, 예: ldap://ldap.myorg.com,ldaps://ldap.myorg.com:636, 이 경우 연결 과정에서 오류가 있으면 서버가 순서대로 시도돼요.
  • starttls (bool, optional) — true이면 암호화되지 않은 연결을 설정한 후 StartTLS 명령을 실행해요.
  • insecure_tls (bool, optional) — true이면 LDAP 서버 SSL 인증서 검증을 건너뛰어요. 안전하지 않으니 주의해서 사용하세요!
  • certificate (string, optional) — LDAP 서버 인증서를 검증할 때 사용할 CA 인증서. x509 PEM 인코딩이어야 해요.
  • client_tls_cert (string, optional) — LDAP 서버에 제공할 클라이언트 인증서. x509 PEM 인코딩이어야 해요.
  • client_tls_key (string, optional) — LDAP 서버에 제공할 클라이언트 인증서 키. x509 PEM 인코딩이어야 해요.
  • schema (string, optional) — 항목 비밀번호를 저장하는 데 사용되는 LDAP 스키마를 정의해요. 지원 값은 openldap과 ad예요. schema 파라미터는 OpenLDAP에는 선택 사항이지만 Active Directory에는 필수예요.

바인딩 파라미터 (Binding parameters)

LDAP 인증 방식은 최종 사용자를 인증하는 데 사용되는 사용자 객체를 해결하는 다음 방법을 지원해요:

  • 검색 (Search) — 제공된 사용자 이름을 기반으로 LDAP 서버 디렉토리에서 사용자 객체를 검색해요. Vault는 두 가지 방법으로 검색할 수 있어요:
    • 인증 검색 (Authenticated search) — 바인드 사용자는 binddn과 bindpass로 설정되어야 해요.
    • 익명 검색 (Anonymous search) — discoverdn이 true로 설정되어야 해요.
  • 사용자 계정 이름 (UPN) — UPN은 Active Directory가 지원하는 사용자 지정 방법이에요. 자세한 UPN 정보는 Active Directory Domain Services 문서의 사용자 이름 지정 속성 페이지를 참고하세요.
바인딩 - 인증 검색 (Binding - authenticated search)
  • binddn (string, optional) — 사용자 및 그룹 검색을 수행할 때 바인드할 객체의 Distinguished Name. 예: cn=vault,ou=Users,dc=example,dc=com
  • bindpass (string, optional) — 사용자 검색을 수행할 때 binddn과 함께 사용할 비밀번호.
  • userdn (string, optional) — 사용자 검색을 수행할 기본 DN. 예: ou=Users,dc=example,dc=com
  • userattr (string, optional) — 인증 시 전달된 사용자 이름과 일치하는 사용자 속성 객체의 속성. 예: sAMAccountName, cn, uid
  • userfilter (string, optional) — ldap 사용자 검색 필터를 구성하는 데 사용되는 Go 템플릿. 템플릿은 다음 컨텍스트 변수에 접근할 수 있어요: [UserAttr, Username]. 기본 userfilter는 ({{.UserAttr}}={{.Username}}) 또는 upndomain 파라미터가 설정되면 (userPrincipalName={{.Username}}@UPNDomain)이에요. 사용자 검색 필터를 사용해 로그인을 시도할 수 있는 사용자를 제한할 수 있어요. 예를 들어 비계약자를 제외한 사용자로 로그인을 제한하려면 (&(objectClass=user)({{.UserAttr}}={{.Username}})(!(employeeType=Contractor)))를 쓸 수 있어요.

userfilter를 지정할 때 템플릿 값 {{.UserAttr}} 또는 userattr과 일치하는 리터럴 값이 필터에 있어야 검색이 userattr을 고려하고 엔티티 별칭 매핑을 위한 고유 결과를 반환하며 로그인 시 가능한 충돌을 피할 수 있어요.

바인딩 - 익명 검색 (Binding - anonymous search)
  • discoverdn (bool, optional) — true이면 익명 바인드를 사용해 사용자의 바인드 DN을 찾아요.
  • userdn (string, optional) — 사용자 검색을 수행할 기본 DN. 예: ou=Users,dc=example,dc=com
  • userattr (string, optional) — 인증 시 전달된 사용자 이름과 일치하는 사용자 속성 객체의 속성. 예: sAMAccountName, cn, uid
  • userfilter (string, optional) — ldap 사용자 검색 필터를 구성하는 데 사용되는 Go 템플릿. 템플릿은 다음 컨텍스트 변수에 접근할 수 있어요: [UserAttr, Username]. 기본 userfilter는 ({{.UserAttr}}={{.Username}}) 또는 upndomain 파라미터가 설정되면 (userPrincipalName={{.Username}}@UPNDomain)이에요. 사용자 검색 필터를 사용해 로그인을 시도할 수 있는 사용자를 제한할 수 있어요. 예를 들어 비계약자를 제외한 사용자로 로그인을 제한하려면 (&(objectClass=user)({{.UserAttr}}={{.Username}})(!(employeeType=Contractor)))를 쓸 수 있어요.
  • anonymous_group_search (bool, optional) — LDAP 그룹 검색을 수행할 때 익명 바인드를 사용해요. 기본값은 false예요.

userfilter를 지정할 때 템플릿 값 {{.UserAttr}} 또는 userattr과 일치하는 리터럴 값이 필터에 있어야 합니다.

별칭 역참조 (Alias dereferencing)
  • dereference_aliases (string, optional) — 검색을 수행할 때 별칭이 역참조되는 방식을 제어해요. 가능한 값: never, finding, searching, always. finding은 베이스의 이름 해석 중에만 별칭을 역참조해요. searching은 이름 해석 후 별칭을 역참조해요.
바인딩 - 사용자 계정 이름 (AD)
  • upndomain (string, optional) — 인증 사용자의 UPN 문자열을 구성하는 데 사용되는 userPrincipalDomain. 구성된 UPN은 [username]@UPNDomain으로 나타나요. 예: example.com은 vault가 [email protected]으로 바인드하게 해요.
  • enable_samaccountname_login (bool: false) — (Optional) upndomain 파라미터가 설정될 때 Active Directory LDAP 사용자가 sAMAccountName 또는 userPrincipalName으로 로그인하게 해요.

인증서 (Certificates)

시작 시 Vault는 certificate 파라미터에서 CA 인증서를 읽는 대신 운영 체제(OS) 인증서 신뢰 저장소에서 LDAP 인증서를 읽을 수 있어요. 시작 후에는 새 인증서를 읽으려면 LDAP 플러그인이 구성된 서버 주소로 새 LDAP 연결을 설정하는 데 정보를 사용하기 전에 Vault를 다시 시작해야 해요.

그룹 멤버십 해결 (Group membership resolution)

사용자가 인증된 후 LDAP 인증 방식은 사용자가 소속된 그룹을 어떻게 해결할지 알아야 해요. 이 구성은 LDAP 서버와 디렉토리 스키마에 따라 달라질 수 있어요. 그룹 멤버십을 해결할 때 두 가지 주요 전략이 있어요 - 첫 번째는 인증된 사용자 객체를 검색하고 소속된 그룹으로 속성을 따라가는 것이에요. 두 번째는 인증된 사용자가 소속된 그룹 객체를 검색하는 것이에요. 두 방법 모두 지원돼요.

  • groupfilter (string, optional) — 그룹 멤버십 query를 구성할 때 사용되는 Go 템플릿. 템플릿은 다음 컨텍스트 변수에 접근할 수 있어요: [UserDN, Username]. 기본값은 (|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))이며 여러 일반 디렉토리 스키마와 호환돼요. Active Directory의 중첩 그룹 해결을 지원하려면 (&(objectClass=group)(member:1.2.840.113556.1.4.1941:={{.UserDN}})) query를 대신 사용하세요.
  • groupdn (string, required) — 그룹 멤버십 검색에 사용할 LDAP 검색 베이스. 그룹 또는 사용자를 포함하는 루트일 수 있어요. 예: ou=Groups,dc=example,dc=com
  • groupattr (string, optional) — 사용자 그룹 멤버십을 열거하기 위해 groupfilter가 반환한 객체에서 따라갈 LDAP 속성. 예: group 객체를 반환하는 groupfilter query에는 cn을 사용하세요. user 객체를 반환하는 query에는 memberOf를 사용하세요. 기본값은 cn이에요.

참고: 바인딩 파라미터에 인증 검색을 사용할 때(위 참고) 그룹 검색에는 binddn에 정의된 Distinguished Name이 사용돼요. 그렇지 않으면 그룹 검색을 수행하는 데 인증 사용자가 사용돼요.

자세한 내용은 vault path-help를 사용하세요.

루트 시크릿 회전 (Root secret rotation)

적절한 Vault Enterprise 라이선스가 필요해요.

  • rotation_schedule (string: "") — cron 스타일 시간 형식의 일정으로, Vault가 루트 토큰을 회전해야 하는 일정을 정의해요.
  • rotation_window (string: "") — 예정된 토큰 회전이 발생할 때 회전을 완료하는 데 허용되는 최대 시간(기간 형식).
  • rotation_period (string: "") — Vault가 루트 크레덴셜을 회전하기 전에 기다려야 하는 시간(기간 형식).
  • rotation_url (string: "") — url 파라미터와 다르면 루트 구성 비밀번호 회전을 수행할 LDAP 서버. 자세한 내용은 (#rotation-url)을 참고하세요.

기타 (Other)

  • username_as_alias (bool, optional) — true로 설정하면 인증 방식이 사용자가 전달한 사용자 이름을 별칭 이름으로 강제로 사용해요.
  • max_page_size (int, optional) — 0보다 큰 값으로 설정하면 LDAP 백엔드가 LDAP 서버의 페이징 검색 제어를 사용해 지정된 크기까지 페이지를 요청해요. 이를 사용해 LDAP 서버의 최대 결과 크기 제한에 부딪히는 것을 피할 수 있어요. 그렇지 않으면 LDAP 백엔드는 페이징 검색 제어를 사용하지 않아요.

루트 크레덴셜 회전 (Root credential rotation)

루트 bindpass를 운영자가 접근할 수 없는 Vault 생성 값으로 회전할 수 있어요. 이는 오직 Vault만이 크레덴셜을 조작하는 데 사용하는 "root" 사용자에 접근할 수 있도록 보장해요.

수동 루트 회전은 vault.log에 로그되고 회전이 on user request였음을 명시해요.

vault write -f auth/ldap/config/rotate-root

Vault는 수동 루트 회전을 vault.log에 로그하고 회전이 on user request였음을 주지해요.

일정 기반 루트 크레덴셜 회전 (Schedule-based root credential rotation)

적절한 Vault Enterprise 라이선스가 필요해요.

rotation_schedule 필드를 사용해 LDAP 인증 엔진의 루트 크레덴셜에 대한 일정 기반 자동 크레덴셜 회전을 구성해요. 예를 들어 다음 명령은 매주 토요일 자정(00:00)에 회전이 발생하도록 설정해요:

$ vault write auth/ldap/config \
    ...
    rotation_schedule="0 * * * SAT"
    ...

예정된 루트 크레덴셜 회전은 예정된 회전이 발생하도록 허용되는 rotation_window를 설정할 수도 있어요. Vault는 창이 만료되면 크레덴셜 회전 시도를 중지해요. 예를 들어 다음 명령은 Vault에게 토요일 자정에 크레덴셜을 회전하되 1시간 범위 내에서만 그렇게 하라고 지시해요. Vault가 실패 등으로 1:00까지 크레덴셜을 회전할 수 없으면 다음 예정된 회전까지 회전 시도를 중지해요.

$ vault write auth/ldap/config \
    ...
    rotation_window="1h" \
    rotation_schedule="0 * * * SAT"
    ...

disable_automated_rotation을 true로 설정해 루트 회전을 일시적으로 비활성화할 수 있어요. disable_automated_rotation 필드를 설정하면 필드가 false로 재설정될 때까지 루트 크레덴셜의 모든 회전을 방지해요. rotation_period를 사용하면 disable_automated_rotation 설정 또한 크레덴셜 TTL을 재설정해요.

회전 URL (Rotation URL)

rotation_url을 사용해 크레덴셜 회전을 위한 바인드 계정이 속한 특정 LDAP 서버 URL을 제공해요. 기본적으로 rotation_url은 url의 값을 사용해요. 명시적 rotation_url 파라미터를 설정하는 것은 로드 밸런서 뒤의 단일 도메인에만 바인드 계정이 속하는 LDAP 포리스트를 구성해야 할 때 유용해요.

LDAP 플러그인의 루트 크레덴셜 회전에 대한 자세한 내용은 루트 크레덴셜 회전 API 문서를 참고하세요.

회전 로깅 (Rotation logging)

Vault Enterprise는 성공 또는 실패한 회전 시 표준 vault.log에 로그를 출력해요.

성공의 경우 Vault는 다음을 주지해요:

  • 첫 번째 파라미터인 rotationID로 회전된 크레덴셜.
  • 다음 회전의 예상 시각을 expire_time으로.

실패의 경우 Vault는 rotationID를 err로 설정하고 구성된 로그 수준에 따라 추가 로그를 출력할 수 있어요.

예시 시나리오 (Examples scenarios)

시나리오 1 (Scenario 1)

  • LDAP 서버가 ldap.example.com, 포트 389에서 실행 중.
  • 서버가 표준 포트에서 암호화를 시작하는 STARTTLS 명령을 지원.
  • CA 인증서가 ldap_ca_cert.pem 파일에 저장됨.
  • 서버가 userPrincipalName 속성을 지원하는 Active Directory. 사용자가 [email protected]으로 식별됨.
  • 그룹이 중첩되어 있으며 LDAP_MATCHING_RULE_IN_CHAIN을 사용해 상위 그래프를 탐색.
  • 그룹 검색은 ou=Groups,dc=example,dc=com 아래에서 시작. 그 경로 아래의 모든 그룹 객체에 대해 member 속성이 인증된 사용자와 일치하는지 확인.
  • 그룹 이름은 cn 속성을 사용해 식별.
$ vault write auth/ldap/config \
    url="ldap://ldap.example.com" \
    userdn="ou=Users,dc=example,dc=com" \
    groupdn="ou=Groups,dc=example,dc=com" \
    groupfilter="(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={{.UserDN}}))" \
    groupattr="cn" \
    upndomain="example.com" \
    certificate=@ldap_ca_cert.pem \
    insecure_tls=false \
    starttls=true
...

시나리오 2 (Scenario 2)

  • LDAP 서버가 ldap.example.com, 포트 389에서 실행 중.
  • 서버가 표준 포트에서 암호화를 시작하는 STARTTLS 명령을 지원.
  • CA 인증서가 ldap_ca_cert.pem 파일에 저장됨.
  • 서버가 사용자 검색을 위한 익명 바인드를 허용하지 않음.
  • 검색에 사용되는 바인드 계정은 비밀번호 My$ecrt3tP4ss로 cn=vault,ou=users,dc=example,dc=com.
  • 사용자 객체가 ou=Users,dc=example,dc=com 조직 단위 아래에 있음.
  • 인증 시 vault에 전달된 사용자 이름이 sAMAccountName 속성에 매핑.
  • 그룹 멤버십은 user 객체의 memberOf 속성을 통해 해결됨. 그 검색은 ou=Users,dc=example,dc=com 아래에서 시작.
$ vault write auth/ldap/config \
    url="ldap://ldap.example.com" \
    userattr=sAMAccountName \
    userdn="ou=Users,dc=example,dc=com" \
    groupdn="ou=Users,dc=example,dc=com" \
    groupfilter="(&(objectClass=person)(uid={{.Username}}))" \
    groupattr="memberOf" \
    binddn="cn=vault,ou=users,dc=example,dc=com" \
    bindpass='My$ecrt3tP4ss' \
    certificate=@ldap_ca_cert.pem \
    insecure_tls=false \
    starttls=true
...

시나리오 3 (Scenario 3)

  • LDAP 서버가 ldap.example.com, 포트 636 (LDAPS)에서 실행 중.
  • CA 인증서가 ldap_ca_cert.pem 파일에 저장됨.
  • 사용자 객체가 ou=Users,dc=example,dc=com 조직 단위 아래에 있음.
  • 인증 시 vault에 전달된 사용자 이름이 uid 속성에 매핑.
  • 사용자 바인드 DN이 익명 바인딩을 사용해 자동으로 찾아짐.
  • 그룹 멤버십은 memberUid, member, uniqueMember 속성 중 하나를 통해 해결됨. 그 검색은 ou=Groups,dc=example,dc=com 아래에서 시작.
  • 그룹 이름은 cn 속성을 사용해 식별.
$ vault write auth/ldap/config \
    url="ldaps://ldap.example.com" \
    userattr="uid" \
    userdn="ou=Users,dc=example,dc=com" \
    discoverdn=true \
    groupdn="ou=Groups,dc=example,dc=com" \
    certificate=@ldap_ca_cert.pem \
    insecure_tls=false \
    starttls=true
...

LDAP 그룹 → 정책 매핑 (LDAP group -> policy mapping)

다음으로 LDAP 그룹에서 Vault 정책으로의 매핑을 만들고 싶어요:

$ vault write auth/ldap/groups/scientists policies=foo,bar

이것은 LDAP 그룹 "scientists"를 "foo"와 "bar" Vault 정책에 매핑해요. 특정 LDAP 사용자를 추가 (잠재적으로 비 LDAP) 그룹에 추가할 수도 있어요. 정책은 LDAP 사용자에도 지정될 수 있음을 주목하세요.

$ vault write auth/ldap/groups/engineers policies=foobar
$ vault write auth/ldap/users/tesla groups=engineers policies=zoobar

이것은 LDAP 사용자 "tesla"를 "foobar" Vault 정책에 매핑하는 "engineers" 그룹에 추가해요. "tesla" 사용자 자체는 "zoobar" 정책과 연관돼요.

마지막으로 인증으로 이를 테스트할 수 있어요:

$ vault login -method=ldap username=tesla
Password (will be hidden):
Successfully authenticated! The policies that are associated
with this token are listed below:

default, foobar, zoobar

정책 매핑에 관한 참고 사항 (Note on policy mapping)

사용자 → 정책 매핑은 토큰 생성 시점에 발생한다는 점을 주의해야 해요. LDAP 서버의 그룹 멤버십 변경은 이미 프로비저닝된 토큰에 영향을 주지 않아요. 이 변경을 보려면 이전 토큰을 폐기하고 사용자에게 다시 인증을 요청해야 해요.

사용자 잠금 (User lockout)

사용자가 연속해서 여러 번 잘못된 크레덴셜을 제공하면 Vault는 잠시 동안 크레덴셜 검증 시도를 중지하고 대신 permission denied 오류로 즉시 반환해요. 이 동작을 "사용자 잠금"이라고 불러요. 사용자가 잠겨 있는 시간을 "잠금 지속 시간(lockout duration)"이라고 해요. 사용자는 잠금 지속 시간이 지난 후 로그인할 수 있어요. 사용자가 잠긴 실패한 로그인 시도 횟수를 "잠금 임계값(lockout threshold)"이라고 해요. 잠금 임계값 카운터는 로그인 시도 없이 몇 분 후 또는 성공적인 로그인 시도 후 0으로 재설정돼요. 로그인 시도가 없을 때 카운터가 0으로 재설정되는 시간을 "잠금 카운터 재설정(lockout counter reset)"이라고 해요. 이는 자동화된 요청과 대상화된 요청, 즉 사용자 기반 비밀번호 추측 공격과 자동화된 공격을 모두 무력화할 수 있어요.

참고: 사용자 잠금은 요청 처리 초기에 발생하며 유효하고 기존의 사용자 계정 이름의 유효성 또는 존재에 대한 정보를 누출할 수 있어요.

사용자 잠금 기능은 기본적으로 활성화돼요. "lockout threshold"의 기본값은 5회 시도, "lockout duration"은 15분, "lockout counter reset"은 15분이에요.

사용자 잠금 기능은 다음과 같이 비활성화할 수 있어요:

  • 환경 변수 VAULT_DISABLE_USER_LOCKOUT을 사용해 전역적으로 비활성화할 수 있어요.
  • 구성 파일의 user_lockout 스탠자 안에 disable_lockout 파라미터를 사용해 지원되는 모든 인증 방식(ldap, userpass, approle) 또는 특정 지원 인증 방식에 대해 비활성화할 수 있어요. 자세한 내용은 user lockout 구성을 참고하세요.
  • "auth tune"을 사용해 특정 인증 마운트에 대해 비활성화할 수 있어요. 자세한 내용은 auth tune 명령 또는 auth tune api를 참고하세요.

참고: 이 기능은 Vault 1.13 버전부터 사용할 수 있으며 userpass, ldap, approle 인증 방식만 지원해요.

API

LDAP 인증 방식은 완전한 HTTP API를 제공해요. 자세한 내용은 LDAP 인증 방식 API를 참고하세요.

Terraform

Vault Terraform 프로바이더로 LDAP 인증 리소스를 프로그래밍 방식으로 관리할 수 있어요. 자세한 내용은 Terraform Registry 문서를 참고하세요.

더 알아보기 (Learn more)