Teleport 역할 템플릿
조직이 성장함에 따라 인프라 팀은 사람들이 팀에 합류하거나, 떠나거나, 새로운 팀을 구성할 때마다 수동 구성이 필요하지 않은 접근 제어 정책을 정의하는 방법을 찾아야 합니다. 다음은 이러한 정책의 일반적인 예입니다: Teleport의 역할 템플릿이 이러한 정책과 다른 정책들을 어떻게 설명하는지 살펴보겠습니다.
조직이 성장함에 따라 인프라 팀은 사람들이 팀에 합류하거나, 떠나거나, 새로운 팀을 구성할 때마다 수동 구성이 필요하지 않은 접근 제어 정책을 정의하는 방법을 찾아야 합니다.
다음은 이러한 정책의 일반적인 예입니다:
- 모든 싱글 사인온 사용자에게 이메일로 생성된 SSH 로그인을 부여합니다.
- 각 팀원을 해당 팀의 Kubernetes 그룹에 할당합니다.
- 개발팀의 데이터베이스 접근을 읽기 전용 복제본으로 제한합니다.
Teleport의 역할 템플릿이 이러한 정책과 다른 정책들을 어떻게 설명하는지 살펴보겠습니다.
사전 요구 사항#
-
A running Teleport cluster. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.
-
The
tctlandtshclients.Installing `tctl` and `tsh` clients
-
Determine the version of your Teleport cluster. The
tctlandtshclients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at/v1/webapi/findand use a JSON query tool to obtain your cluster version. Replace with the web address of your Teleport Proxy Service:$ TELEPORT_DOMAIN= $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')" -
Follow the instructions for your platform to install
tctlandtshclients:
-
To check that you can connect to your Teleport cluster, sign in with tsh login, then
verify that you can run tctl commands using your current credentials.
For example, run the following command, assigning to the domain name of the Teleport Proxy Service in your cluster and to your Teleport username:
$ tsh login --proxy= --user=
$ tctl status
# Cluster (=teleport.url=)
# Version (=teleport.version=)
# CA pin (=presets.ca_pin=)
If you can connect to the cluster and run the tctl status command, you can use your
current credentials to run subsequent tctl commands from your workstation.
If you host your own Teleport cluster, you can also run tctl commands on the computer that
hosts the Teleport Auth Service for full permissions.
로컬 사용자#
Alice와 Bob이라는 두 사용자가 있다고 가정합니다. 다음과 같은 접근 정책을 설정하려고 합니다:
- Alice는 SSH 사용자
admin과 Kubernetes 그룹edit으로 로그인할 수 있습니다. - Bob은
ubuntu와 Kubernetes 그룹view로 로그인할 수 있습니다.
roles.yaml 파일에 각 사용자에 대한 역할을 두 개 만들 수 있습니다:
kind: role
version: v7
metadata:
name: alice
spec:
allow:
logins: ['admin']
kubernetes_groups: ['edit']
node_labels:
'*': '*'
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: '*'
namespace: '*'
name: '*'
verbs: ['*']
---
kind: role
version: v7
metadata:
name: bob
spec:
allow:
logins: ['ubuntu']
kubernetes_groups: ['view']
node_labels:
'*': '*'
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: '*'
namespace: '*'
name: '*'
verbs: ['*']
역할을 만들고 Alice와 Bob을 로컬 사용자로 초대할 수 있습니다:
$ tctl create -f roles.yaml
$ tctl users add alice --roles=alice
$ tctl users add bob --roles=bob
사용자별로 하나의 역할을 갖는 것은 확장성이 좋지 않습니다. 역할이 매우 유사하기 때문에 각 사용자에게 변수를 할당하고, Alice와 Bob 모두에게 단 하나의 역할 템플릿만 사용할 수 있습니다.
devs.yaml이라는 역할 템플릿을 만들어 봅시다:
kind: role
version: v7
metadata:
name: devs
spec:
allow:
logins: ['{{internal.logins}}']
kubernetes_groups: ['{{internal.kubernetes_groups}}']
node_labels:
'*': '*'
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: '*'
namespace: '*'
name: '*'
verbs: ['*']
역할은 템플릿 변수를 사용하기 시작하면 템플릿이 됩니다.
역할과 마찬가지로 역할 템플릿도 유효한 YAML이며 구조와 타입 모두 유효성을 검사합니다.
역할 템플릿 devs는 internal 표기법을 사용하여 로컬 사용자의 속성인 logins와 kubernetes_groups를 참조합니다. internal 표기법은 제한된 사전 정의 속성 세트만 지원합니다. 로컬 사용자와 함께 사용자 정의 속성을 사용하는 경우 external.<trait-name> 구문을 사용하세요.
역할 템플릿을 만들려면 tctl을 사용하세요:
$ tctl create -f devs.yaml
마지막 단계는 Alice와 Bob의 사용자 속성을 업데이트하는 것입니다. 다음은 traits.yaml이라는 파일에 있는 사용자 리소스의 예입니다:
kind: user
version: v2
metadata:
name: alice
spec:
roles: ['devs']
traits:
logins: ['admin']
kubernetes_groups: ['edit']
---
kind: user
version: v2
metadata:
name: bob
spec:
roles: ['devs']
traits:
logins: ['ubuntu']
kubernetes_groups: ['view']
tctl create -f 명령으로 두 사용자의 항목을 업데이트합니다:
$ tctl create -f traits.yaml
# user "alice" has been updated
Alice가 로그인하면 새 역할로 SSH 및 X.509 인증서를 받게 됩니다. SSH 로그인과 Kubernetes 그룹도 설정됩니다:
$ tsh login --proxy=teleport.example.com --user=alice
# > Profile URL: https://teleport.example.com:443
# Logged in as: alice
# Cluster: teleport.example.com
# Roles: devs*
# Logins: admin
# Kubernetes: enabled
# Kubernetes groups: edit
# Valid until: 2021-03-26 07:13:57 -0700 PDT [valid for 12h0m0s]
# Extensions: permit-port-forwarding, permit-pty
$ tsh login --proxy=mytenant.teleport.sh --user=alice
# > Profile URL: https://mytenant.teleport.sh:443
# Logged in as: alice
# Cluster: mytenant.teleport.sh
# Roles: devs*
# Logins: admin
# Kubernetes: enabled
# Kubernetes groups: edit
# Valid until: 2021-03-26 07:13:57 -0700 PDT [valid for 12h0m0s]
# Extensions: permit-port-forwarding, permit-pty
SSO 사용자#
아이덴티티 프로바이더 관리자는 사용자에게 그룹 멤버십이나 접근 권한과 같은 메타데이터를 할당할 수 있습니다. 관리자는 어떤 메타데이터가 Teleport와 공유되는지 구성합니다. Teleport는 싱글 사인온 리다이렉트 플로우 중에 OIDC 클레임 또는 SAML 속성으로 사용자 메타데이터 키와 값을 받습니다:
# Alice의 이메일은 alice@example.com입니다. 이메일은 표준 OIDC 클레임입니다.
email: "alice@example.com"
# Alice는 admins와 devs 그룹의 멤버입니다.
groups: ["admins", "devs"]
# 그녀는 prod와 staging 환경에 접근할 수 있습니다.
env: ["prod", "staging"]
아이덴티티 프로바이더에 의해 외부 속성 logins가 설정될 것으로 예상하는 sso-users라는 역할 템플릿을 만들어 봅시다. 이 역할을 sso-users.yaml로 저장합니다:
kind: role
version: v7
metadata:
name: sso-users
spec:
allow:
logins: ['{{external.logins}}']
node_labels:
'*': '*'
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: '*'
namespace: '*'
name: '*'
verbs: ['*']
github.yaml이라는 GitHub 커넥터는 octocats 조직의 cyber 팀의 모든 멤버를 sso-users 역할에 매핑합니다:
kind: github
version: v3
metadata:
name: github
spec:
# GitHub OAuth app의 클라이언트 ID
client_id: client-id
# GitHub OAuth app의 클라이언트 시크릿
client_secret: secret-data-here
# 웹 UI 로그인 화면에 표시될 커넥터 이름
display: GitHub
# 성공적인 인증 후 호출될 콜백 URL
redirect_url: https://teleport.example.com/v1/webapi/github/callback
# org/team 멤버십을 허용된 Teleport 역할에 매핑
teams_to_roles:
- organization: octocats # GitHub 조직 이름
team: cyber # 해당 조직 내 GitHub 팀 이름
# 매핑할 역할 이름
roles:
- sso-users
tctl을 사용하여 이 커넥터를 만듭니다:
$ tctl create -f github.yaml
Bob이 SSO를 통해 로그인하면 sso-users 역할 템플릿을 사용하여 생성된 SSH 로그인으로 새 역할과 SSH 및 X.509 인증서를 받게 됩니다:
$ tsh login --proxy=teleport.example.com --auth=github
#> Profile URL: https://teleport.example.com:443
# Logged in as: bob
# Cluster: teleport.example.com
# Roles: sso-users*
# Logins: bob
# Kubernetes: enabled
# Kubernetes groups: edit
# Valid until: 2021-03-26 07:13:57 -0700 PDT [valid for 12h0m0s]
# Extensions: permit-port-forwarding, permit-pty
$ tsh login --proxy=mytenant.teleport.sh --auth=github
#> Profile URL: https://mytenant.teleport.sh:443
# Logged in as: bob
# Cluster: mytenant.teleport.sh
# Roles: sso-users*
# Logins: bob
# Kubernetes: enabled
# Kubernetes groups: edit
# Valid until: 2021-03-26 07:13:57 -0700 PDT [valid for 12h0m0s]
# Extensions: permit-port-forwarding, permit-pty
보간 규칙#
관리자는 싱글 사인온 중에 아이덴티티 프로바이더가 반환하는 속성을 구성하고 Teleport에 제공할 수 있습니다. 몇 가지 시나리오를 검토하고 Teleport가 변수를 어떻게 보간하는지 살펴보겠습니다.
Alice 사용자 항목의 속성 목록으로 돌아가 보겠습니다:
# Alice의 이메일은 alice@example.com입니다. 이메일은 표준 OIDC 클레임입니다.
email: "alice@example.com"
# Alice는 admins와 devs 그룹의 멤버입니다.
groups: ["admins", "devs"]
# 그녀는 prod와 staging 환경에 접근할 수 있습니다.
env: ["prod", "staging"]
이 변수들이 역할 템플릿 interpolation과 함께 어떻게 사용되는지 살펴보겠습니다:
kind: role
version: v7
metadata:
name: interpolation
spec:
allow:
# 역할 템플릿 필드는 하드코딩된 값과 변수를 혼합할 수 있습니다.
logins: ['{{external.logins}}', 'admin']
# 역할은 문자열 값에서 보간을 지원합니다.
kubernetes_users: ['IAM#{{external.email}};']
# 목록은 목록으로 확장됩니다.
kubernetes_groups: ['{{external.groups}}']
# 함수는 변수를 변환합니다.
database_users: ['{{email.local(external.email)}}']
db_labels:
'env': '{{regexp.replace(external.env, "^(staging)$", "$1")}}'
# 레이블은 템플릿과 하드코딩된 값을 혼합할 수 있습니다.
node_labels:
'env': '{{external.env}}'
'region': 'us-west-2'
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: '*'
namespace: '*'
name: '*'
verbs: ['*']
Alice의 SSO 사용자 속성으로 보간한 후 역할 템플릿은 다음 역할처럼 동작합니다:
kind: role
version: v7
metadata:
name: interpolation
spec:
allow:
# 변수 external.logins는 프로바이더에서 전송되지 않아 비어있으므로
# 하드코딩된 admin 값만 남습니다.
logins: ['admin']
# 변수 external.email은 문자열에서 확장됩니다.
kubernetes_users: ['IAM#alice@example.com;']
# 변수 external.groups는 목록으로 대체됩니다.
kubernetes_groups: ['devs', 'admins']
# 함수 email.local은 external.email 속성의 로컬 부분을 가져옵니다.
database_users: ['alice']
# 함수 regexp.replace는 일치하는 값만 변환하고 필터링합니다.
db_labels:
'env': 'staging'
# 노드 레이블은 변수에서 'env'가 대체되고 'region'은 하드코딩됩니다.
node_labels:
'env': ['prod', 'staging']
'region': 'us-west-2'
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: '*'
namespace: '*'
name: '*'
verbs: ['*']
사용 가능한 보간 함수#
사용 가능한 보간 함수는 다음과 같습니다:
| 함수 | 설명 |
|---|---|
email.local(variable) |
이메일 주소의 로컬 부분을 추출합니다. email.local(alice@example.com)은 alice로 평가됩니다. |
regexp.replace(variable, expression, replacement) |
expression의 모든 일치 항목을 찾아 replacement로 대체합니다. 확장을 지원합니다(예: regexp.replace(external.email, "^(.*)@example.com$", "$1")). 표현식과 일치하지 않는 값은 필터링됩니다. $N은 $1부터 시작하는 N번째 캡처 그룹을 참조하는 데 사용됩니다. |
외부 이메일 아이덴티티로 작업하기#
SSO 프로바이더는 그룹을 보내는 것과 함께 사용자의 이메일 주소도 제공합니다. 많은 조직에서 사람들이 시스템에 로그인하는 데 사용하는 사용자 이름은 이메일 주소의 첫 번째 부분, 즉 "로컬" 부분과 동일합니다.
예를 들어, dave.smith@example.com은 dave.smith라는 사용자 이름으로 로그인할 수 있습니다. Teleport는 이메일 주소의 첫 번째 부분을 추출하여 사용자 이름으로 사용할 수 있는 편리한 방법을 제공합니다. 이것이 {{email.local}} 함수입니다.
아이덴티티 프로바이더에서 보낸 이메일 클레임({{external.email}}을 통해 접근 가능)이 이메일 주소를 포함하는 경우, @ 기호 앞의 "로컬" 부분을 다음과 같이 추출할 수 있습니다:
{{email.local(external.email)}}
이것이 Teleport 역할에서 어떻게 보이는지 예시입니다:
kind: role
version: v5
metadata:
name: sso_user
spec:
allow:
logins:
# dave.smith@acme.com의 로컬 부분을 추출하므로 로그인은
# 이제 dave.smith를 지원합니다.
- '{{email.local(external.email)}}'
node_labels:
'*': '*'
접근 요청의 템플릿#
접근 요청과 검토자 요청 사양은 로그인, 레이블 등과 동일한 보간 시스템을 사용하지 않습니다. 대신 request와 review_requests 규칙의 claims_to_roles 절을 사용하여 일치시킬 하나 이상의 패턴을 지정할 수 있습니다.
예를 들어, request 구성에 대한 다음 규칙 템플릿이 있다고 가정합니다:
kind: role
version: v3
metadata:
name: product-admin
spec:
allow:
request:
# `roles`는 `product-admin` 역할을 가진 사용자가 임시 접근을 요청할 수 있는 정적 역할 목록입니다.
roles: [access]
claims_to_roles:
- claim: 'projects'
value: '^product-(.*)$' # 'product-'로 시작하는 모든 그룹 이름과 일치
roles: ['$1-admin'] # 값 캡처에서 역할 이름을 생성
예를 들어, Alice에게 product-admin 역할을 부여하고 projects 속성에 일부 항목을 추가할 수 있습니다:
kind: user
version: v2
metadata:
name: alice
spec:
roles: ['dev', 'product-admin']
traits:
projects: ['internal-tooling', 'product-alpha', 'product-beta']
이 경우 Alice는 RBAC 역할 access(정적 역할 목록에서)와 alpha-admin 및 beta-admin(claims_to_roles 매핑에서)에 대한 접근을 요청할 수 있습니다.
동일한 구문이 검토 요청에도 적용됩니다.
