권한 부여
텔레포트는 인증과 권한 부여를 모두 처리합니다.
- 인증은 사용자 또는 서비스의 신원을 증명하는 것입니다.
- 권한 부여는 무언가에 대한 접근 권한을 증명하는 것입니다.
이 문서는 RBAC를 사용한 사용자 및 서비스의 권한 부여에 대해 다룹니다.
사용자 및 역할
텔레포트는 여러 유형의 사용자 계정을 지원합니다:
- 대화형 및 비대화형.
- 로컬 및 외부.
각 사용자는 성공적인 인증 후 하나 이상의 역할과 연결됩니다.
대화형 사용자
대화형 사용자는 로컬 또는 외부일 수 있습니다. 로컬 사용자 계정은 텔레포트의 백엔드에 로그인 자격 증명 - 비밀번호 해시 및 MFA 장치 데이터를 저장합니다. 외부 사용자 계정은 SSO 프로토콜 - OAuth 2.0, OIDC 또는 SAML을 사용하여 제3자 신원 제공자가 인증합니다.
SSO 제공자로부터의 외부 사용자
텔레포트를 사용하여 자신의 조직의 SSO 공급자를 사용하여 인증하는 앨리스의 예를 살펴보겠습니다:
SSO 사용자가 로그인할 때마다, 텔레포트는 SSO 세션과 자동으로 만료되며 감사 로그 항목이 기록되는 임시 사용자 계정 기록을 생성합니다.
텔레포트는 로컬 사용자와의 이름 충돌을 방지하기 위해 이 기록을 생성합니다.
다른 클러스터의 외부 사용자
사용자는 다른 클러스터 또는 인증 기관에서 이 클러스터가 신뢰하는 인증서를 발급받으면 텔레포트 클러스터 외부일 수 있습니다. 이 경우 텔레포트는 신뢰할 수 있는 클러스터 매핑 로직을 활성화합니다.
로컬 대화형 사용자
로컬 대화형 사용자는 자격 증명이 있는 텔레포트의 백엔드에 기록이 있습니다.
클러스터 관리자는 tctl users add
또는 API 호출을 사용하여 각 텔레포트 사용자에 대한 계정 항목을 생성해야 합니다.
모든 로컬 텔레포트 사용자는 하나 이상의 역할 목록과 연결되어야 합니다. 이 목록을 "역할 매핑"이라고 합니다.
비대화형 사용자
텔레포트는 Jenkins 또는 귀하의 조직에서 실행되는 마이크로 서비스와 같은 자동화 서비스를 위한 비대화형 사용자도 지원합니다.
로컬 비대화형 사용자
로컬 비대화형 사용자도 역할에 대한 이름을 매핑하는 사용자 항목을 가지고 있지만, 데이터베이스에 저장된 자격 증명은 없습니다. 비대화형 사용자는 텔레포트의 머신 ID 제품을 사용하여 인증서를 수신하고 갱신해야 합니다. 텔레포트 머신 ID의 봇은 서비스와 함께 실행되며 비대화형 사용자를 대신하여 SSH 및 X.509 인증서를 교체합니다:
외부 비대화형 사용자
외부 비대화형 사용자는 로컬 사용자와 같이 작동하지만, 인증서는 다른 클러스터 또는 인증 기관에서 발급됩니다.
그들은 텔레포트 백엔드에 로컬 사용자 기록이 없습니다. 텔레포트는 이 사용 사례를 지원하기 위해 신뢰할 수 있는 클러스터 매핑 로직을 활성화합니다.
역할 기반 접근 제어
모든 텔레포트 사용자는 리소스와 텔레포트 API에 대한 접근을 제어하는 하나 이상의 역할이 할당됩니다.
허용 및 거부 규칙
각 텔레포트 역할은 두 개의 규칙 목록: 허용
규칙 및 거부
규칙으로 작동합니다:
- 기본적으로 모든 것이 거부됩니다.
- 거부 규칙이 먼저 평가되며 우선권을 가집니다.
- 규칙은 두 부분으로 구성됩니다: 리소스와 동사.
다음은 세션 리소스에 적용되는 목록 동사를 설명하는 허용 규칙의 예입니다. 이것은 "이 역할의 사용자에게 기록된 SSH 또는 Kubernetes 세션 목록을 볼 수 있도록 허용"을 의미합니다.
allow:
- resources: [session]
verbs: [list]
주체(Principals)
역할은 사용자가 역할에 할당될 수 있는 주체(예: Linux OS 사용자 또는 Kubernetes 그룹)를 정의합니다:
spec:
allow:
# logins 배열은 사용자가 사용할 수 있는 OS/UNIX 로그인을 정의합니다.
logins: [ubuntu]
# Kubernetes 그룹은 사용자가 가질 수 있는 Kubernetes 그룹을 정의합니다.
kubernetes_groups: [viewer]
사용자가 여러 역할을 가지고 있는 경우, 주체 목록은 하나의 집합으로 병합됩니다.
레이블(Labels)
역할 레이블은 역할의 규칙이 적용되는 리소스를 정의합니다. 예를 들어, SSH 노드와 Kubernetes 클러스터에 대한 접근을 지정하는 역할을 살펴보겠습니다:
spec:
allow:
# 사용자가 연결할 수 있는 노드 레이블 목록:
node_labels:
# 정규 표현식도 지원됩니다. 예를 들어 위의 목록 예제와 동일한 내용을 표현할 수 있습니다:
'environment': '^test|staging$'
kubernetes_labels:
# 사용자는 us-west의 모든 지역에 접근할 수 있습니다, 예를 들어 us-west-1, us-west-2
'region': 'us-west-*'
'cluster_name': '^us.*\.example\.com$'
레벨, 허용 규칙 및 주체가 적용되는 방식은 다음과 같습니다:
허용
규칙이 일치하려면 규칙의 모든 레이블이 일치해야 합니다. 예를 들어 Kubernetes 규칙에서region
과cluster_name
모두 일치해야 합니다.거부
규칙이 일치하려면 규칙의 레이블 중 하나라도 일치할 수 있습니다.
주체 및 레이블
앨리스에게 dev
와 prod
두 가지 역할이 할당되었다고 가정해 보겠습니다:
Dev 역할은 root
로 SSH 접근을 허용하고, 'test' 또는 'stage' 레이블이 있는 모든 Kubernetes 클러스터 또는 노드에 대한 제한 없는 접근을 허용합니다.
metadata:
name: dev
spec:
allow:
logins: [root]
kubernetes_groups: ['system:masters']
# 사용자가 연결할 수 있는 노드 레이블 목록:
node_labels:
'environment': ['test', 'stage']
kubernetes_labels:
'environment': ['test', 'stage']
# 위에서 지정된 레이블이 있는 클러스터의 모든 Kubernetes 리소스에 접근을 허용합니다.
kubernetes_resources:
- kind: '*'
namespace: '*'
name: '*'
verbs: ['*']
Prod 역할은 ubuntu
로 SSH 접근을 허용하고,
'prod' 레이블이 있는 모든 Kubernetes 클러스터 또는 노드에 대한 view
접근을 허용합니다.
metadata:
name: prod
spec:
allow:
logins: [ubuntu]
kubernetes_groups: ['view']
node_labels:
'environment': ['prod']
kubernetes_labels:
'environment': ['prod']
kubernetes_resources:
- kind: '*'
namespace: '*'
name: '*'
verbs: ['*']
텔레포트가 앨리스의 접근을 평가하는 방법은 다음과 같습니다:
- 앨리스는 'test' 또는 'stage'로 레이블된 서버에 SSH로 root로 접속할 수 있습니다.
- 앨리스는 'prod' 레이블이 있는 서버에 SSH로 root로 접속할 수 없습니다. 왜냐하면 prod 역할은 'prod' 레이블이 있는 서버에
ubuntu
로 접근할 수 있도록만 허용하기 때문입니다.
Kubernetes에도 동일하게 적용됩니다:
- 앨리스는 'test' 또는 'stage'로 레이블된 클러스터에 대해
system:masters
역할로 접속할 수 있습니다. - 앨리스는
prod
로 레이블된 클러스터에 대해서는view
역할로만 accessing할 수 있습니다.
역할 템플릿
역할은 템플릿 변수를 지원합니다. 다음은 변수가 보간되는 방식에 대해 설명하는 역할 스니펫입니다.
spec:
# 허용 섹션은 이 역할의 사용자에게 허용되는 리소스/동사 조합의 목록을 선언합니다.
# 기본적으로 아무것도 허용되지 않습니다.
allow:
# internal.logins - 로컬 사용자의 특성에서 보간됩니다 -
# 사용자를 생성할 때 할당할 수 있는 속성입니다.
logins: ['{{internal.logins}}']
# kubernetes_groups는 이 역할의 사용자가 가질 Kubernetes 그룹을 지정합니다.
# SAML/OIDC 특성을 "external" 속성 집합을 통해 참조할 수 있습니다.
# 이를 통해 신원 관리자의 Kubernetes 그룹 직위를 지정할 수 있습니다:
kubernetes_groups: ['{{external.groups}}']
변수 보간을 사용하는 모든 역할은 역할 템플릿으로 간주됩니다. 어떤 역할 설정에도 보간을 추가할 수 있습니다.
**변수 보간 규칙 *
- 만약
external.groups
가["dev", "prod"]
를 포함하는 목록이라면, 표현식["{{external.groups}}"]
는 목록["dev", "prod"]
로 보간됩니다. - 만약
external.groups
가"dev"
와 같은 변수를 포함한다면, 표현식["{{external.groups}}"]
는["dev"]
로 보간됩니다. - 만약
external.groups
가 존재하지 않으면 표현식"{{external.groups}}"
는 빈 문자열""
로 평가됩니다. - 템플릿에서 함수 호출과 같은 조건부 언어를 사용할 수 있습니다. 예를 들어
{{email.local(external.foo)}}
와 같습니다. - 문자 접두사와 값을 조합할 수 있습니다. 예를 들어
"IAM#{{regexp.replace(external.foo, "^bar-(.*)$", "$1")}};"
. - 잘못된 표현식은 무시됩니다. 예를 들어
external.foo}}
는 생략되며, 잘못된 함수 호출과 같습니다. - 잘못된 값은 생략됩니다. 예를 들어
-foo
는 유효한 Unix 로그인 형식이 아니므로, 만약 변수external.foo
가"-foo"
일 경우,logins: ["{{external.foo}}"]
에서 생략됩니다.
텔레포트 역할에서 변수 확장이 작동하는 모든 세부 사항은 텔레포트 접근 제어 참조를 참조하세요.
역할 템플릿의 평가 방법
역할 템플릿은 프록시 또는 노드의 리소스 접근 시 평가됩니다. 모든 텔레포트 구성요소 - 프록시, 인증 서버 또는 노드는 모든 역할의 최신 사본을 가지고 있습니다.
다음은 다음과 같은 역할 템플릿을 검토해 보겠습니다:
metadata:
name: devs
spec:
allow:
kubernetes_groups: ["{{external.k8s_groups}}"]
kubernetes_labels:
"env": ["{{external.env}}"]
kubernetes_resources:
- kind: pod
namespace: "*"
name: "*"
사용자 앨리스가 텔레포트에서 인증을 받고 신원 제공자로부터 다음과 같은 변수를 받습니다:
k8s_groups: ["view", "edit"]
env: ["stage"]
이 변수들은 X.509 인증서에 확장으로 인코딩됩니다.
프록시가 Kubernetes 클러스터에 연결하려는 시도를 승인할 때, 역할 템플릿과 변수를 보간하여 다음과 같이 됩니다:
metadata:
name: devs
spec:
allow:
kubernetes_groups: ["view", "edit"]
kubernetes_labels:
"env": ["stage"]
kubernetes_resources:
- kind: pod
namespace: "*"
name: "*"
마지막으로, 프록시는 앨리스가 접근하려는 Kubernetes 클러스터에 결과 역할을 적용하고 클러스터에 대해 검증합니다. 클러스터의 레이블이 "env": "stage"
인 경우 접근이 성공하고, 그렇지 않으면 실패합니다.
역할 조건
다음 예제는 세션에 대한 접근을 세션을 생성한 사용자만 제한하는 방법을 보여줍니다:
kind: role
metadata:
name: only-own-sessions
spec:
allow:
rules:
# 사용자는 자신이 참여한 세션의 세션 녹화만 볼 수 있습니다.
- resources: [session]
verbs: [list, read]
where: contains(session.participants, user.metadata.name)
모든 리소스 규칙에서 where
필드를 사용할 수 있습니다. 모든 세부 사항은 전체 역할 참조를 확인하세요.
역할 옵션
허용
및 거부
규칙 외에도 역할은 다음과 같은 다양한 옵션을 제어합니다:
kind: role
version: v5
metadata:
name: relaxed
spec:
# 옵션은 사용자가 여러 비기본 충돌 옵션을 가질 경우 연결을 지정합니다.
# 텔레포트는 가장 보수적인 값을 선택합니다.
options:
# max_session_ttl은 이 역할의 사용자에게 발급되는 인증서의 TTL(시간 제한)을 정의합니다.
max_session_ttl: 8h
# lock은 이 역할의 사용자를 위한 잠금 모드를 설정합니다.
# 유효한 값은 "strict" 또는 "best_effort"입니다.
lock: strict
사용자가 여러 역할을 가지고 있으며 충돌 옵션을 지정하는 경우, 예를 들어 역할 relaxed
가 max_session_ttl
을 8h
로 설정하고 restricted
가 max_session_ttl
을 4h
로 설정하는 경우, 가장 안전한 값이 사용됩니다. 이 경우 텔레포트는 세션을 4시간으로 제한하기로 선택합니다.
텔레포트는 다른 값에 대해서도 동일한 논리를 적용합니다. 예를 들어 두 역할이 strict
및 best_effort
옵션을 모두 지정할 경우 텔레포트는 strict
옵션을 선택합니다.
즉시 접근 요청(Just in Time Access Requests)
즉시 접근 요청의 전체 버전은 텔레포트 엔터프라이즈( 엔터프라이즈 클라우드 포함)에서만 제공됩니다.
역할은 다른 역할이나 개별 리소스에 대해 권한 상승을 요청할 수 있습니다.
역할은 누가 권한 요청을 검토할 수 있는지 제어하며, 필요한 승인 또는 거부의 수를 정의합니다:
spec:
allow:
# review_requests 역할을 가진 사용자가
# 접근 요청을 승인하거나 거부할 수 있도록 허용합니다.
review_requests:
roles: ['dbadmin']
# request 사용자가 아래 표현식과 일치하는 역할을 요청할 수 있습니다.
request:
# `roles` 목록은 리터럴 및 와일드카드 일치자가 혼합될 수 있습니다.
roles: ['common', 'dev-*']
# thresholds는 최소한의 승인자 및 거부자 수를 지정합니다.
# 기본값은 둘 다 1입니다.
thresholds:
# 최소 두 명의 승인자와 최소 한 명의 거부자가 필요합니다.
- approve: 2
deny: 1