로그인 규칙 설정
Teleport v18.9로그인 규칙은 사용자가 Teleport에 로그인할 때 SSO 프로바이더가 제공하는 외부 속성을 변환하는 로직을 정의하여 클러스터의 사용자에게 일관된 접근 제어 정책을 제공합니다. 이 가이드는 Teleport 클러스터에 첫 번째 로그인 규칙을 작성, 테스트 및 추가하는 과정을 안내합니다.
로그인 규칙은 사용자가 Teleport에 로그인할 때 SSO 프로바이더가 제공하는 외부 속성을 변환하는 로직을 정의하여 클러스터의 사용자에게 일관된 접근 제어 정책을 제공합니다. Teleport 관리자는 로그인 규칙을 사용하여 IdP 구성을 변경하지 않고도 사용자 속성의 변환을 정의할 수 있습니다. 이는 조직의 아이덴티티 프로바이더(IdP)를 관리하는 팀이 Teleport를 관리하는 팀과 분리된 경우에 특히 유용합니다.
이 가이드는 Teleport 클러스터에 첫 번째 로그인 규칙을 작성, 테스트 및 추가하는 과정을 안내합니다.
작동 방식#
로그인 규칙은 Auth Service 백엔드에 저장된 동적 Teleport 리소스입니다. 사용자가 IdP를 통해 Teleport에 인증하면 Teleport는 IdP의 데이터를 기반으로 사용자의 외부 속성을 채웁니다. 로그인 규칙은 사용자의 외부 속성을 조작하기 위한 로직을 정의합니다. 사용자가 Teleport에 로그인하면 Teleport Auth Service는 우선순위 순서로 로그인 규칙을 실행합니다. 모든 로그인 규칙을 실행한 후 Auth Service는 사용자에게 발급하는 인증서에 최종 외부 속성 세트를 인코딩합니다.
로그인 규칙 구성에 대한 자세한 내용은 로그인 규칙 참조를 참조하세요.
사전 요구 사항#
-
실행 중인 Teleport Enterprise 클러스터. Teleport를 시작하려면 무료 체험판에 가입하거나 데모 환경을 구성하세요.
-
tctlandtshclients.Installing `tctl` and `tsh` clients
-
Teleport 클러스터의 버전을 확인합니다.
tctlandtshclients는 Teleport 클러스터 버전보다 최대 한 개의 메이저 버전까지만 뒤처질 수 있습니다. Proxy Service의/v1/webapi/find로 GET 요청을 보내고 JSON 쿼리 도구를 사용하여 클러스터 버전을 확인합니다.teleport.example.com:443를 Teleport Proxy Service의 웹 주소로 바꿉니다:$ TELEPORT_DOMAIN=teleport.example.com:443 $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')" -
사용 중인 플랫폼에 대한 지침에 따라
tctlandtshclients를 설치합니다:
-
Mac
`tctl` and `tsh` clients가 포함된, 서명된 Teleport macOS .pkg 설치 프로그램을 다운로드합니다:
```code
$ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
```
Finder에서 `pkg` 파일을 더블 클릭하여 설치를 시작합니다.
Homebrew를 사용하여 Teleport를 설치하는 것은 지원되지 않습니다. Homebrew의
Teleport 패키지는 Teleport에서 유지 관리하지 않으므로 신뢰성이나 보안을
보장할 수 없습니다.
Windows - Powershell
```code
$ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
# Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
# NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
# Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
```
Linux
Linux 설치판의 모든 Teleport 바이너리에는 `tctl` and `tsh` clients가 포함되어 있습니다. RPM/DEB
패키지 및 i386/ARM/ARM64용 다운로드를 포함한 더 많은 옵션은
[설치 페이지](../installation/installation.mdx)를 참조하세요.
```code
$ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
$ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
$ cd teleport
$ sudo ./install
# Teleport binaries have been copied to /usr/local/bin
```
Teleport cluster에 연결할 수 있는지 확인하려면 tsh login으로 로그인한 다음,
현재 자격 증명으로 tctl 명령을 실행할 수 있는지 확인합니다.
예를 들어, teleport.example.com에 cluster 내 Teleport Proxy Service의
도메인 이름을, email@example.com에 Teleport 사용자 이름을 지정하여
다음 명령을 실행합니다:
$ tsh login --proxy=teleport.example.com --user=email@example.com
$ tctl status
# Cluster (=teleport.url=)
# Version (=teleport.version=)
# CA pin (=presets.ca_pin=)
cluster에 연결하여 tctl status 명령을 실행할 수 있다면, 현재 자격 증명을 사용하여
워크스테이션에서 이후의 tctl 명령을 실행할 수 있습니다.
자체 Teleport cluster를 호스팅하는 경우, 전체 권한을 얻기 위해 Teleport Auth Service를
호스팅하는 컴퓨터에서 tctl 명령을 실행할 수도 있습니다.
시작하기 전에 버전 11.3.1 이상의 실행 중인 Teleport Enterprise 또는 Cloud 클러스터가 있어야 합니다.
로그인 규칙은 SSO 로그인에서만 작동하므로 시작하기 전에 OIDC, SAML 또는 GitHub 커넥터를 구성했는지 확인합니다. 설정 방법은 싱글 사인온 문서를 확인하세요.
1/5단계. RBAC 구성#
먼저 login_rule 리소스를 읽고 수정할 수 있는 권한이 있는 사용자로 Teleport에 로그인했는지 확인합니다. 사전 설정 editor 역할에는 이미 이 접근 권한이 있지만, 더 사용자 정의된 구성을 사용하는 경우 다음 내용으로 loginrule-manager.yaml이라는 역할을 만듭니다:
kind: role
metadata:
name: loginrule-manager
spec:
allow:
rules:
- resources: [login_rule]
verbs: [list, create, read, update, delete]
version: v7
tctl로 역할을 만듭니다:
$ tctl create loginrule-manager.yaml
role 'loginrule-manager' has been created
Web UI를 사용하여 역할을 생성하고 편집할 수도 있습니다. Access -> Roles로 이동하여 Create New Role을 클릭하거나 편집할 기존 역할을 선택하십시오.
인증 공급자에 맞는 적절한 명령을 실행하여 loginrule-manager 역할을
your Teleport user에게 할당하십시오:
Local User
-
로컬 사용자의 역할을 쉼표로 구분된 목록으로 가져옵니다:
$ ROLES=$(tsh status -f json | jq -r '.active.roles | join(",")') -
로컬 사용자를 편집하여 새 역할을 추가합니다:
$ tctl users update $(tsh status -f json | jq -r '.active.username') \ --set-roles "${ROLES?},loginrule-manager" -
Teleport 클러스터에서 로그아웃한 다음 다시 로그인하여 새 역할을 적용합니다.
GitHub
-
텍스트 편집기에서
github인증 커넥터를 엽니다:$ tctl edit github/github -
github커넥터를 편집하여teams_to_roles섹션에loginrule-manager을 추가합니다.이 역할에 매핑해야 할 팀은 조직의 역할 기반 액세스 제어(RBAC)를 어떻게 설계했는지에 따라 달라집니다. 다만, 해당 팀은 여러분의 사용자 계정을 포함해야 하며 조직 내에서 가능한 한 가장 작은 팀이어야 합니다.
다음은 예시입니다:
teams_to_roles: - organization: octocats team: admins roles: - access + - loginrule-manager -
편집기에서 파일을 저장하고 닫아 변경 사항을 적용합니다.
-
Teleport 클러스터에서 로그아웃한 다음 다시 로그인하여 새 역할을 적용합니다.
SAML
-
saml구성 리소스를 가져옵니다:$ tctl get --with-secrets saml/mysaml > saml.yaml--with-secrets플래그는spec.signing_key_pair.private_key값을saml.yaml파일에 추가한다는 점에 유의하십시오. 이 키에는 민감한 값이 포함되어 있으므로, 리소스를 업데이트한 직후 saml.yaml 파일을 삭제해야 합니다. -
saml.yaml을 편집하여attributes_to_roles섹션에loginrule-manager을 추가합니다.이 역할에 매핑해야 할 속성은 조직의 역할 기반 액세스 제어(RBAC)를 어떻게 설계했는지에 따라 달라집니다. 다만, 해당 그룹은 여러분의 사용자 계정을 포함해야 하며 조직 내에서 가능한 한 가장 작은 그룹이어야 합니다.
다음은 예시입니다:
attributes_to_roles: - name: "groups" value: "my-group" roles: - access + - loginrule-manager -
변경 사항을 적용합니다:
$ tctl create -f saml.yaml -
Teleport 클러스터에서 로그아웃한 다음 다시 로그인하여 새 역할을 적용합니다.
OIDC
-
oidc구성 리소스를 가져옵니다:$ tctl get oidc/myoidc --with-secrets > oidc.yaml--with-secrets플래그는spec.signing_key_pair.private_key값을oidc.yaml파일에 추가한다는 점에 유의하십시오. 이 키에는 민감한 값이 포함되어 있으므로, 리소스를 업데이트한 직후 oidc.yaml 파일을 삭제해야 합니다. -
oidc.yaml을 편집하여claims_to_roles섹션에loginrule-manager을 추가합니다.이 역할에 매핑해야 할 클레임은 조직의 역할 기반 액세스 제어(RBAC)를 어떻게 설계했는지에 따라 달라집니다. 다만, 해당 그룹은 여러분의 사용자 계정을 포함해야 하며 조직 내에서 가능한 한 가장 작은 그룹이어야 합니다.
다음은 예시입니다:
claims_to_roles: - name: "groups" value: "my-group" roles: - access + - loginrule-manager -
변경 사항을 적용합니다:
$ tctl create -f oidc.yaml -
Teleport 클러스터에서 로그아웃한 다음 다시 로그인하여 새 역할을 적용합니다.
2/5단계. 로그인 규칙 리소스 초안 작성#
다음 예제는 모든 사용자에게 현재 username 속성의 값을 소문자로 변환한 새 logins 속성을 부여합니다. 가이드를 계속 진행하기 위해 이 예제 규칙을 my_rule.yaml 파일에 복사합니다.
# my_rule.yaml
kind: login_rule
version: v1
metadata:
# 각 로그인 규칙은 클러스터 내에서 고유한 이름을 가져야 합니다.
name: my_rule
# expires는 선택 사항이며 배포된 로그인 규칙에는 일반적으로 설정하지 않아야 하지만,
# 새 로그인 규칙을 테스트할 때 잠재적으로 Teleport 클러스터에서 잠기는 것을 방지하기 위해
# 가까운 미래로 만료를 설정하는 것이 유용할 수 있습니다.
# expires: "2023-01-31T00:00:00-00:00"
spec:
# priority는 클러스터에 여러 로그인 규칙이 있는 경우 로그인 규칙의 평가 순서를 정합니다.
# 낮은 우선순위가 먼저 평가됩니다.
priority: 0
# traits_expression은 로그인 중에 각 SSO 사용자의 최종 속성을 결정하기 위해
# 평가될 술어 표현식입니다.
#
# 이 예제 표현식은 "logins" 속성을 소문자로 변환된
# 들어오는 "username" 속성으로 설정합니다.
traits_expression: 'external.put("logins", strings.lower(external["username"]))'
각 로그인 규칙 리소스에는 traits_map 또는 traits_expression 필드가 있어야 합니다. 이 가이드에서는 예제 traits_expression을 사용합니다.
traits_expression은 로그인하는 각 SSO 사용자의 속성을 결정하기 위해 런타임에 Teleport 클러스터에서 평가될 스크립트 형식입니다. 표현식은 external 변수를 통해 사용자의 들어오는 속성에 접근할 수 있습니다. external 변수는 속성 키를 해당 속성 값의 세트에 매핑하는 딕셔너리입니다.
3/5단계. 로그인 규칙 테스트#
tctl login_rule test 명령은 새 로그인 규칙을 실험하여 구문을 확인하고 예제 들어오는 속성에서 어떻게 작동하는지 정확히 확인하는 데 사용할 수 있습니다.
사용자의 현재 속성을 가져와 input.json에 저장한 다음 해당 입력으로 새 로그인 규칙을 테스트합니다.
$ tctl get --format json users/username | jq 'first.spec.traits' > input.json
$ tctl login_rule test --resource-file my_rule.yaml input.json
access:
- staging
groups:
- dbs
- devs
logins:
- alice
이 스크립트는 표현식의 구문 오류를 잡아냅니다. 예상되는 모든 속성이 출력에 있는지 확인합니다.
4/5단계. 로그인 규칙 만들기#
다음 명령을 사용하여 클러스터에 로그인 규칙을 만듭니다:
$ tctl create my_rule.yaml
5/5단계. 확인#
마지막 단계로 클러스터에서 로그아웃한 다음 다시 로그인하여 사용자가 예상되는 속성과 역할을 받았는지 확인합니다. 다음 명령으로 속성과 역할을 확인할 수 있습니다:
$ tctl get --format json users/username | jq '{traits: first.spec.traits, roles: first.spec.roles}'
{
"traits": {
"access": [
"staging"
],
"groups": [
"dbs",
"devs"
],
"logins": [
"alice"
]
},
"roles": [
"access",
"editor",
"auditor"
]
}
문제 해결#
tctl sso test 명령은 SSO 로그인을 디버깅하고 SSO 프로바이더에서 전송 중인 속성과 로그인 규칙에 의해 어떻게 매핑되는지 정확히 확인하는 데 사용할 수 있습니다.
tctl sso test는 커넥터 사양을 기대합니다. 클러스터에 현재 설치된 커넥터로 디버깅하려면 다음 명령을 실행합니다. SSO connector name을 Teleport에 등록한 SSO 커넥터의 이름으로 교체합니다:
$ tctl get connector/SSO connector name --with-secrets | tctl sso test
다음 단계#
로그인 규칙 표현 구문에 대해 자세히 알아보려면 로그인 규칙 참조 페이지를 확인하세요.
도움말 명령을 실행하거나 참조 페이지를 확인하여 tctl login_rule test 명령에 대해 알아보세요.
$ tctl help login_rule test
다음 tctl 리소스 명령은 클러스터에 현재 설치된 로그인 규칙을 보고 수정하는 데 유용합니다.
| 명령 | 설명 |
|---|---|
tctl get login_rules |
클러스터에 설치된 모든 로그인 규칙 표시. |
tctl get login_rule/<rule_name> |
특정 설치된 로그인 규칙 가져오기. |
tctl create login_rule.yaml |
새 로그인 규칙 설치. |
tctl create -f login_rule.yaml |
기존 로그인 규칙 덮어쓰기. |
tctl rm login_rule/<rule_name> |
로그인 규칙 삭제. |
예제 로그인 규칙#
임의의 비표준 JSON 클레임이 있는 OIDC 프로바이더 사용#
표준 OIDC 클레임은 문자열 값과 목록으로 구성됩니다. 그러나 비표준 JSON 클레임을 반환하는 프로바이더가 있을 수도 있습니다. 기본적으로 Teleport는 claims_to_roles 매핑이나 사용자의 Teleport 속성에 이러한 클레임을 읽으려고 시도하지 않습니다.
예를 들어 여러 다른 프로바이더 소스의 사용자 클레임을 집계하는 사용자 정의 분산 IdP를 상상해 봅니다. 클레임 세트는 다음 형식의 JSON 객체처럼 보일 수 있습니다:
{
"aggregated_claims": {
"okta": {
"groups": "okta_dev"
},
"auth0": {
"groups": "auth0_devops"
}
}
}
다음 JSONPath 표현식은 이러한 클레임을 가져와 표준 groups 클레임으로 보간합니다:
kind: login_rule
version: v1
metadata:
name: set_logins
spec:
priority: 1
traits_expression: |
external.put("groups", jsonpath("$.aggregated_claims.*.groups"))
위의 클레임과 로그인 규칙으로 로그인하는 사용자는 다음과 같은 클레임을 가진 것처럼 처리됩니다:
{
"groups": [
"okta_dev",
"auth0_devops"
]
}
이러한 보간된 클레임은 클레임-역할 매핑에 사용될 수 있으며, 표준 클레임과 마찬가지로 Teleport 속성으로 유지됩니다.
그룹당 정적 값 목록으로 속성 설정#
kind: login_rule
version: v1
metadata:
name: example
spec:
priority: 0
traits_expression: |
external.put("allow-env",
choose(
option(external.group.contains("dev"), set("dev", "staging")),
option(external.group.contains("qa"), set("qa", "staging")),
option(external.group.contains("admin"), set("dev", "qa", "staging", "prod")),
option(true, set()),
))
OIDC/SAML 프로바이더에서 제공하는 특정 속성만 사용#
groups 및 email 속성만 원래 값으로 유지하려면:
kind: login_rule
version: v1
metadata:
name: example
spec:
priority: 0
traits_map:
groups:
- external.groups
email:
- external.email
특정 속성 제거#
특정 속성을 제거하고 나머지는 유지하려면:
kind: login_rule
version: v1
metadata:
name: example
spec:
priority: 0
traits_expression: |
external.remove("big-trait")
특정 속성에 추가 값 추가#
kind: login_rule
version: v1
metadata:
name: example
spec:
priority: 0
traits_expression: |
external.add_values("logins", "ubuntu", "ec2-user")
다른 규칙에서 하나의 로그인 규칙의 출력 사용#
kind: login_rule
version: v1
metadata:
name: set_groups
spec:
priority: 0
traits_expression: |
external.put("groups",
ifelse(external.groups.contains("admins"),
external["groups"].add("superusers"),
external["groups"]))
---
kind: login_rule
version: v1
metadata:
name: set_logins
spec:
priority: 1
traits_expression: |
ifelse(external.groups.contains("superusers"),
external.add_values("logins", "root"),
external)