Infograb logo
텔레포트 역할 템플릿

조직이 성장함에 따라 인프라 팀은 사람들이 합류하고 떠나고 새로운 팀을 구성할 때마다 수동 구성이 필요하지 않은 접근 제어 정책을 정의하는 방법을 알아내야 합니다.

다음은 이러한 정책의 몇 가지 일반적인 예입니다:

  • 모든 SSO 사용자가 자신의 이메일에서 생성된 SSH 로그인을 허용합니다.
  • 각 팀원을 해당 팀의 Kubernetes 그룹에 할당합니다.
  • 개발 팀은 데이터베이스에 대한 읽기 전용 복제로 제한합니다.

텔레포트의 역할 템플릿이 이러한 정책을 설명하는 방법을 살펴보겠습니다.

필수 조건

  • 실행 중인 Teleport 클러스터 버전 이상. Teleport를 시작하려면, 가입하기 위해 무료 평가판에 등록하거나 데모 환경 설정하기를 참조하세요.

  • tctl 관리 도구와 tsh 클라이언트 도구.

    tctltsh 다운로드에 대한 지침은 설치를 방문하세요.

  • 당신의 Teleport 클러스터에 연결할 수 있는지 확인하려면, tsh login으로 로그인한 다음 현재 자격 증명을 사용하여 tctl 명령어를 실행할 수 있는지 확인하십시오. 예를 들어:
    tsh login --proxy=teleport.example.com --user=email@example.com
    tctl status

    클러스터 teleport.example.com

    버전 16.2.0

    CA 핀 sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

    클러스터에 연결하고 tctl status 명령어를 실행할 수 있다면, 현재 자격 증명을 사용하여 작업대에서 후속 tctl 명령어를 실행할 수 있습니다. 자신의 Teleport 클러스터를 호스팅하는 경우, Teleport 인증 서비스를 호스팅하는 컴퓨터에서 전체 권한으로 tctl 명령어를 실행할 수도 있습니다.

로컬 사용자

앨리스와 밥이라는 두 명의 사용자가 있다고 가정해 보겠습니다. 다음과 같은 접근 정책을 설정하고자 합니다:

  • 앨리스는 SSH 사용자 admin으로 로그인하고 Kubernetes 그룹 edit에 속할 수 있습니다.
  • 밥은 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: ['*']

역할을 생성하고 앨리스와 밥을 로컬 사용자로 초대할 수 있습니다:

tctl create -f roles.yaml
tctl users add alice --roles=alice
tctl users add bob --roles=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는 로컬 사용자 특성인 loginskubernetes_groups를 참조하기 위해 internal 표기법을 사용하고 있습니다. internal 표기법은 제한된 수의 미리 정의된 특성만 지원합니다. 로컬 사용자와 함께 사용자 지정 특성을 사용할 경우, external.<trait-name> 구문을 사용하십시오.

tctl을 사용하여 역할 템플릿을 생성합니다:

tctl create -f devs.yaml

마지막 단계는 앨리스와 밥의 사용자에 특성을 업데이트하는 것입니다. 다음은 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

사용자 "alice"가 업데이트되었습니다.

앨리스가 로그인하면 새로운 역할로 SSH 및 X.509 인증서를 받게 됩니다. SSH 로그인이자 Kubernetes 그룹도 설정됩니다:

tsh login --proxy=teleport.example.com --user=alice

> 프로필 URL: https://teleport.example.com:443

로그인한 사용자: alice

클러스터: teleport.example.com

역할: devs*

로그인: admin

Kubernetes: 활성화됨

Kubernetes 그룹: edit

유효 기간: 2021-03-26 07:13:57 -0700 PDT [유효 기간 12시간]

확장: permit-port-forwarding, permit-pty

tsh login --proxy=mytenant.teleport.sh --user=alice

> 프로필 URL: https://mytenant.teleport.sh:443

로그인한 사용자: alice

클러스터: mytenant.teleport.sh

역할: devs*

로그인: admin

Kubernetes: 활성화됨

Kubernetes 그룹: edit

유효 기간: 2021-03-26 07:13:57 -0700 PDT [유효 기간 12시간]

확장: permit-port-forwarding, permit-pty

SSO 사용자

아이덴티티 공급자 관리자는 그룹 구성원 자격이나 접근 권한과 같은 메타데이터를 사용자에게 할당할 수 있습니다. 관리자는 Teleport와 공유되는 메타데이터를 구성합니다. Teleport는 OIDC 클레임 또는 SAML 속성으로 사용자 메타데이터 키와 값을 수신합니다. single sign-on redirect flow 동안.

# 앨리스의 이메일은 alice@example.com입니다. 이메일은 표준 OIDC 클레임입니다.
email: "alice@example.com"
# 앨리스는 그룹 admins 및 devs의 구성원입니다.
groups: ["admins", "devs"]
# 그녀는 프로덕션 및 스테이징 환경에 접근할 수 있습니다.
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 커넥터는 조직 octocatscyber 팀의 모든 구성원을 역할 sso-users에 매핑합니다:

kind: github
version: v3
metadata:
  name: github
spec:
  # GitHub OAuth 앱의 클라이언트 ID
  client_id: client-id
  # GitHub OAuth 앱의 클라이언트 비밀번호
  client_secret: secret-data-here
  # 웹 UI 로그인 화면에 표시될 커넥터 표시 이름
  display: GitHub
  # 성공적인 인증 후 호출될 콜백 URL
  redirect_url: https://teleport.example.com/v1/webapi/github/callback
  # 허용된 Teleport 역할에 대한 조직/팀 구성원을 매핑
  teams_to_roles:
    - organization: octocats # GitHub 조직 이름
      team: cyber # 해당 조직 내 GitHub 팀 이름
      # 매핑할 역할 이름
      roles:
        - sso-users

이 커넥터를 tctl을 사용하여 생성합니다:

tctl create -f github.yaml

밥이 SSO를 사용하여 로그인하면, 그는 새로운 역할과 함께 SSH 및 X.509 인증서를 받게 되며 sso-users 역할 템플릿을 사용하여 생성된 SSH 로그인을 받게 됩니다:

tsh login --proxy=teleport.example.com --auth=github

> 프로필 URL: https://teleport.example.com:443

로그인한 사용자: bob

클러스터: teleport.example.com

역할: sso-users*

로그인: bob

Kubernetes: 활성화됨

Kubernetes 그룹: edit

유효 기간: 2021-03-26 07:13:57 -0700 PDT [유효 기간 12시간]

확장: permit-port-forwarding, permit-pty

tsh login --proxy=mytenant.teleport.sh --auth=github

> 프로필 URL: https://mytenant.teleport.sh:443

로그인한 사용자: bob

클러스터: mytenant.teleport.sh

역할: sso-users*

로그인: bob

Kubernetes: 활성화됨

Kubernetes 그룹: edit

유효 기간: 2021-03-26 07:13:57 -0700 PDT [유효 기간 12시간]

확장: permit-port-forwarding, permit-pty

보간 규칙

관리자는 아이덴티티 공급자가 싱글 사인온 중에 Teleport에 반환하는 속성을 구성할 수 있습니다. 몇 가지 시나리오를 검토하고 Teleport가 변수를 어떻게 보간하는지 살펴보겠습니다.

앨리스 사용자 항목의 속성 목록으로 돌아가 보겠습니다:

# 앨리스의 이메일은 alice@example.com입니다. 이메일은 표준 OIDC 클레임입니다.
email: "alice@example.com"
# 앨리스는 그룹 admins 및 devs의 구성원입니다.
groups: ["admins", "devs"]
# 그녀는 프로덕션 및 스테이징 환경에 접근할 수 있습니다.
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: ['*']

앨리스의 SSO 사용자 속성으로 보간되면서, 역할 템플릿은 다음과 같은 역할로 동작합니다:

kind: role
version: v7
metadata:
  name: interpolation
spec:
  allow:
    # 외부.logins 변수는 공급자에 의해 전송되지 않으므로 공백으로 렌더링되어
    # 하드 코딩된 admin 값만 남습니다.
    logins: ['admin']

    # 외부.email 변수는 문자열에서 확장됩니다.
    kubernetes_users: ['IAM#alice@example.com;']

    # 외부.groups 변수가 리스트로 대체됩니다.
    kubernetes_groups: ['devs', 'admins']

    # 함수 email.local은 외부.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: ['*']

사용 가능한 보간 함수는 다음과 같습니다:

FunctionDescription
email.local(variable)이메일 주소의 로컬 부분을 추출합니다. email.local(alice@example.com)alice로 평가됩니다.
regexp.replace(variable, expression, replacement)expression의 모든 일치를 찾아 replacement로 교체합니다. 이는 확장을 지원하며, 예: regexp.replace(external.email, "^(.*)@example.com$", "$1"). 일치하지 않는 값은 필터링됩니다. $N은 캡처된 그룹의 N번째를 참조하는 데 사용됩니다(첫 번째 그룹은 $1).

접근 요청의 템플릿화

접근 및 검토 요청 사양은 로그인의 레이블 등과 동일한 보간 시스템을 사용하지 않습니다. 대신, requestreview 규칙에서 하나 이상의 패턴을 일치시키기 위해 claims_to_roles 절을 사용할 수 있습니다.

예를 들어, 다음 규칙 템플릿을 고려해 보겠습니다:

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']     # 값 캡처에서 역할 이름 생성

앨리스에게 product-admin 역할을 부여하고 projects 특성에 몇 가지 항목을 추가할 수 있습니다:

kind: user
version: v2
metadata:
  name: alice
spec:
  roles: ['dev', 'product-admin']
  traits:
    projects: ['internal-tooling', 'product-alpha', 'product-beta']

이 경우, 앨리스는 RBAC 역할 access(정적 역할 목록에서)와 claims_to_roles 매핑에서 alpha-adminbeta-admin에 대한 접근을 요청할 수 있습니다.

검토 요청에서도 동일한 구문이 적용됩니다.

Teleport 원문 보기