이 가이드는 텔레포트 사용자가 Kubernetes 클러스터와 상호작용할 때 텔레포트 Kubernetes 서비스가 역할 기반 액세스 제어(RBAC)를 적용하는 방법을 설명합니다. Kubernetes 서비스는 Kubernetes API 서버에 대한 요청을 가로채고 각 요청을 사용자의 텔레포트 역할에 따라 수정합니다.
이 가이드에서는 텔레포트 역할에서 사용할 수 있는 필드를 구성하여 텔레포트에 연결된 Kubernetes 클러스터에 대한 액세스를 관리하는 방법을 보여드립니다.
로컬 minikube
클러스터와 함께 Kubernetes에 대한 액세스를 관리하기 위해 텔레포트 역할을 사용하는 방법에 대한 예는 RBAC 사용 방법 가이드를 참조하세요.
Kubernetes 액세스 관리를 위한 역할 필드
이 섹션에서는 Kubernetes 클러스터에 대한 액세스를 구성하는 텔레포트 역할 내의 필드에 대해 설명합니다.
Kubernetes 클러스터에 대한 액세스를 관리하려면 텔레포트 역할은 다음 필드를 spec.allow
섹션에 포함해야 합니다:
Kubernetes 클러스터에 대한 액세스를 제한하는 텔레포트 역할의 예는 다음과 같습니다:
kind: role
metadata:
name: kube-access
version: v7
spec:
allow:
kubernetes_labels:
'region': '*'
'platform': 'minikube'
kubernetes_resources:
- kind: pod
namespace: "production"
name: "^webapp-[a-z0-9-]+$"
- kind: pod
namespace: "development"
name: "*"
kubernetes_groups:
- developers
kubernetes_users:
- minikube
deny: {}
kubernetes_labels
Kubernetes 클러스터를 텔레포트에 등록할 때 레이블을 추가할 수 있습니다. 사용자의 액세스를 서로 다른 레이블이 있는 Kubernetes 클러스터로 제한할 수 있습니다 kubernetes_labels
필드를 사용하는 역할을 통해.
kind: role
metadata:
name: kube-access
version: v7
spec:
allow:
kubernetes_labels:
'region': '*'
'environment': 'development'
# ...
deny: {}
kubernetes_labels
필드의 값은 레이블 키와 하나 이상의 레이블 값 간의 매핑입니다(즉, 문자열 또는 목록).
Kubernetes 서비스가 kubernetes_labels
를 평가하는 방법
레이블의 키와 값이 모두 와일드카드인 경우 *
, 텔레포트 Kubernetes 서비스는 사용자가 모든 레이블이 있는 Kubernetes 클러스터에 액세스하는 것을 허용합니다:
spec:
allow:
kubernetes_labels:
'*': '*'
# ...
그렇지 않으면 Kubernetes 서비스는 kubernetes_labels
의 모든 키가 등록된 Kubernetes 클러스터에 해당하는 키와 일치하는지 확인합니다. 그렇지 않으면 일치하는 Kubernetes 클러스터가 없으며 Kubernetes 서비스는 요청을 거부합니다.
예를 들어, 레이블들이 environment
키를 포함하지만 region
키를 포함하지 않는 클러스터는 위의 kube-access
역할에서 kubernetes_labels
필드와 일치하지 않습니다.
Kubernetes 서비스는 다음으로 kubernetes_labels
의 키에 있는 Kubernetes 클러스터 레이블의 값을 검색합니다. kubernetes_labels
의 각 키의 값은 Kubernetes 클러스터 레이블의 값과 일치해야 사용자가 클러스터에 접근할 수 있습니다.
예를 들어, 위의 kube-access
역할은 사용자가 region
키와 아무 값으로 된 Kubernetes 클러스터에 액세스하는 것을 허용합니다. 이 역할은 environment
키와 development
값이 있는 Kubernetes 클러스터로 사용자를 제한합니다. kubernetes_labels
내의 유효한 키의 값에 대해 다음 섹션에서 설명합니다.
레이블 값
kubernetes_labels
의 레이블 키가 Kubernetes 클러스터의 키와 일치하려면 일치는 정확해야 합니다. 그러나 값의 경우에는 유연성을 제공하기 위해 정규 표현식, 와일드카드 및 여러 값을 구성할 수 있습니다.
정규 표현식 및 와일드카드
정규 표현식 또는 와일드카드 문자를 사용하여 문자열의 하위 집합 또는 변형을 일치시킬 수 있습니다. 값이 ^
로 시작하고 $
로 끝나는 경우 Kubernetes 서비스는 이를 Go의 re2
구문을 사용하는 정규 표현식으로 처리합니다 (참고로 re2
README).
그렇지 않으면 Kubernetes 서비스는 값 내의 와일드카드를 평가하여 레이블에서 문자 시퀀스와 일치하도록 합니다.
예를 들어:
spec:
allow:
kubernetes_labels:
'region': 'us-east-*'
'team': '^data-eng-[a-z-]+$'
# ...
이 allow
규칙은 레이블 region:us-east-1
및 region:us-east-2b
가 있는 클러스터와 일치합니다. 또한 레이블 team:data-eng-analytics
및 team:data-eng-ml-training
이 있는 클러스터와도 일치합니다.
여러 값
kubernetes_labels
의 키가 여러 값을 가진 경우 Kubernetes 서비스는 이러한 값 중 임의의 값이 Kubernetes 클러스터의 레이블과 일치하는 경우 레이블 값을 일치시킬 것입니다. 예를 들어, 이 kubernetes_labels
구성은 레이블이 region:us-east-2
이고 development
또는 staging
환경 중 하나를 가진 클러스터와 일치합니다:
spec:
allow:
kubernetes_labels:
'region': 'us-east-*'
'environment': ['development', 'staging']
# ...
레이블 적용
텔레포트 Kubernetes 서비스의 인스턴스에 레이블을 적용할 수 있습니다. 이를 수행하는 방법은 서비스를 시작한 방법에 따라 다릅니다:
teleport-kube-agent
Helm 차트를 설치하거나 업그레이드할 때 레이블을 설정합니다, 예를 들어:
helm upgrade teleport-agent teleport-kube-agent --set kubeClusterName={CLUSTER?}\ --set proxyAddr=${PROXY?} --set authToken=${TOKEN?} --create-namespace --namespace=teleport-agent\ --set labels.env=prod --set labels.region=us-west-1
텔레포트 인스턴스의 구성 파일에서 텔레포트 Kubernetes 서비스를 활성화할 때 레이블을 설정합니다:
kubernetes_service:
enabled: true
kube_cluster_name: cookie
labels:
env: prod
region: us-west-1
kubernetes_groups
및 kubernetes_users
텔레포트 Kubernetes 서비스는 최종 사용자로부터 요청을 받고(예: kubectl
를 통해) 이를 Kubernetes API 서버에 전달합니다. Kubernetes 서비스는 임시 사용자 헤더를 사용하여 하나의 Kubernetes 사용자와 0개 이상의 Kubernetes 그룹으로 API 서버에 요청을 보냅니다.
kubernetes_users
및 kubernetes_groups
필드는 사용자가 Kubernetes API 서버에 요청을 보낼 때 허용되는 사용자 및 그룹을 나타냅니다:
kind: role
metadata:
name: kube-access
version: v7
spec:
allow:
kubernetes_groups:
- developers
- viewers
kubernetes_users:
- myuser
- system:serviceaccount:someNamespace:saName # 서비스 계정 이름
# ...
deny: {}
kubernetes_groups
및 kubernetes_users
의 값은 사용자가 수신하도록 허용할 그룹, 사용자 또는 서비스 계정의 이름 목록입니다.
Kubernetes 사용자 및 그룹
Kubernetes 사용자 및 그룹은 Kubernetes 클러스터 내에 존재하는 엔터티이며 ClusterRoleBinding
또는 RoleBinding
리소스를 통해 권한이 제어됩니다. 그들이 클러스터에 존재하지 않으면 Kubernetes RBAC는 이를 무시합니다.
다음은 사용자 cluster-viewer-user
와 그룹 cluster-viewer-group
에 내장된 view
ClusterRole
을 할당하는 ClusterRoleBinding
리소스의 예입니다:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: cluster-viewer-group
- apiGroup: rbac.authorization.k8s.io
kind: User
name: cluster-viewer-user
이 시점에서 사용자와 그룹은 Kubernetes 네임스페이스의 리소스를 보는 동일한 권한을 가집니다. Kubernetes는 요청에 사용된 임시 원칙을 통해 혼합된 권한을 가지므로 Kubernetes 사용자 및 그룹에 동일한 권한을 부여할 필요는 없습니다.
Kubernetes 서비스 계정
텔레포트는 서비스 계정의 전체 자격 이름을 사용하여 서비스 계정 임시화를 지원합니다.
서비스 계정의 전체 자격 이름은 다음 패턴으로 구성됩니다:
system:serviceaccount:<namespace>:<service_account_name>
FQN은 반드시 system:serviceaccount:
로 시작해야 Kubernetes에서 이를 일반 사용자로 평가하지 않습니다.
서비스 계정을 임시화하는 역할의 예는 다음과 같습니다.
kind: role
metadata:
name: kube-access-impersonate-sa
version: v7
spec:
allow:
kubernetes_users:
- system:serviceaccount:someNamespace:saName
# ...
deny: {}
텔레포트 사용자가 Kubernetes 사용자, 그룹 및 서비스 계정을 임시화하는 방법
최종 사용자가 어떤 사용자 또는 서비스 계정 및 그룹을 임시화할지 지정하는 방법은 두 가지가 있습니다:
수동으로
사용자가 Kubernetes 클러스터에 대해 인증하기 위해 tsh kube login
을 사용할 때 --as
및 --as-groups
플래그를 사용하여 수동으로 인증할 사용자 및 그룹을 지정할 수 있습니다. 텔레포트 Kubernetes 서비스는 사용자가 지정한 사용자 및 그룹이 사용자의 kubernetes_users
및 kubernetes_groups
구성에 해당되는지 확인하고 그렇지 않은 경우 액세스를 거부합니다.
자동으로
사용자가 클러스터에 인증할 때 Kubernetes 사용자 및 Kubernetes 그룹을 명시적으로 결정하지 않은 경우, 텔레포트 Kubernetes 서비스는 사용자의 역할에 있는 kubernetes_users
및 kubernetes_groups
필드에서 이를 결정합니다.
사용자가 kubernetes_users
에 정확히 하나의 값이 있는 경우 텔레포트 Kubernetes 서비스는 해당 사용자를 임시화합니다. kubernetes_users
에 값이 없으면 Kubernetes 서비스는 사용자의 텔레포트 사용자 이름을 사용합니다.
사용자가 여러 개의 kubernetes_users
가 있고 클러스터에 인증할 때 임시화할 사용자를 지정하지 않은 경우 Kubernetes 서비스는 요청을 거부합니다 (즉, 이전 섹션에서 설명한 --as
플래그를 사용합니다).
사용자가 임시화할 Kubernetes 그룹을 지정하지 않는 경우 Kubernetes 서비스는 kubernetes_groups
의 모든 값을 사용합니다.
위의 kube-access
역할을 통해 텔레포트에 인증한 후, Kubernetes 서비스는 사용자에게 developers
그룹과 myuser
Kubernetes 사용자와 함께 API 서버에 요청을 전달하기 위해 임시화 헤더를 사용합니다.
임시화 활성화
Kubernetes 서비스는 사용자의 요청을 임시화 헤더로 전달할 수 있도록 하려면, 서비스 계정에 클러스터 내에서 Kubernetes RBAC 원칙을 임시화할 수 있는 권한이 필요합니다. Kubernetes 서비스는 사용자가 액세스할 수 없는 사용자 또는 그룹을 임시화 요청은 거부합니다.
아래는 임시화를 활성화하기 위해 필요한 최소 권한 집합을 부여하는 Kubernetes ClusterRole
과 이러한 권한을 서비스 계정에 부여하는 ClusterRoleBinding
입니다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: teleport-impersonation
rules:
- apiGroups:
- ""
resources:
- users
- groups
- serviceaccounts
verbs:
- impersonate
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- "authorization.k8s.io"
resources:
- selfsubjectaccessreviews
verbs:
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: teleport
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: teleport-impersonation
subjects:
- kind: ServiceAccount
name: teleport-serviceaccount
namespace: default
사용자 특성에 따라 그룹 및 사용자 지정
각 텔레포트 사용자별로 Kubernetes 그룹 및 사용자를 지정할 수 있으며, 이러한 정보가 텔레포트 역할에 하드 코딩되지 않도록 할 수 있습니다. 이렇게 하려면 텔레포트 역할에 템플릿 변수를 추가할 수 있으며, 텔레포트 인증 서비스가 각 인증 사용자의 정보로 이를 채웁니다.
템플릿 변수 확장이 텔레포트 역할에서 작동하는 방법에 대한 자세한 내용은 텔레포트 액세스 제어 참조를 참조하십시오.
SSO 공급자 특성
텔레포트의 역할은 템플릿 변수를 사용하여 OIDC 클레임이나 SAML 속성을 매핑합니다. 텔레포트 인증 서비스는 {{external.*}}
형식의 템플릿 변수를 해당하는 SAML 속성 또는 OIDC 클레임으로 대체합니다:
kind: role
version: v7
metadata:
name: group-member
spec:
allow:
kubernetes_groups: ["{{external.groups}}"]
kubernetes_users: ["{{external.kube_username}}"]
# ...
예를 들어, 사용자가 SAML 커넥터를 통해 텔레포트에 인증하고, 사용자에게 kube_username
속성이 myuser
값과 groups
속성이 developers
및 viewers
값을 가진 경우, 위의 group-member
역할은 다음과 같이 평가됩니다:
kind: role
version: v7
metadata:
name: group-member
spec:
allow:
kubernetes_groups: ["developers", "viewers"]
kubernetes_users: ["myuser"]
# ...
로컬 사용자 특성
로컬 사용자의 경우 user
리소스의 spec.traits
필드에 임의의 키-값 데이터를 지정한 다음 역할에서 해당 특성을 참조하기 위해 {{external.*}}
템플릿 변수를 사용할 수 있습니다.
예를 들어, 이 역할은 kubernetes_users
및 kubernetes_groups
를 내부 특성으로 채웁니다:
kind: role
version: v7
metadata:
name: group-member
spec:
allow:
kubernetes_groups: ["{{external.groups}}"]
kubernetes_users: ["{{external.kube_username}}"]
# ...
다음은 이러한 템플릿 변수를 채우기 위해 로컬 사용자 생성 또는 수정 시 값을 제공하는 사용자 정의 정의의 예입니다:
kind: user
version: v2
metadata:
name: alice
spec:
roles:
- group-member
traits:
groups:
- developers
- viewers
kube_username:
- myuser
kubernetes_resources
kubernetes_resources
필드는 텔레포트 역할이 Kubernetes 클러스터 내의 특정 리소스에 대한 액세스를 구성할 수 있게 해줍니다:
kind: role
metadata:
name: kube-access
version: v7
spec:
allow:
kubernetes_labels:
'*':'*'
kubernetes_resources:
- kind: pod
namespace: "production"
name: "webapp"
verbs: ['*']
# ...
이 필드의 값은 각 매핑이 네 개의 필드를 가진 목록입니다:
-
kind
: 액세스를 허용할 리소스의 종류. 현재, 텔레포트는 다음 종류를 지원합니다:Kind Grants access to *
모든 리소스 pod
포드 secret
비밀 configmap
구성 맵 namespace
네임스페이스 및 모든 리소스 포함 service
서비스 serviceaccount
서비스 계정 kube_node
노드 persistentvolume
퍼시스턴트 볼륨 persistentvolumeclaim
퍼시스턴트 볼륨 클레임 deployment
배포 replicaset
복제세트 statefulset
상태 있는 세트 daemonset
데몬 세트 clusterrole
클러스터 역할 kube_role
역할 clusterrolebinding
클러스터 역할 바인딩 rolebinding
역할 바인딩 cronjob
주기적 작업 job
작업 certificatesigningrequest
인증서 서명 요청 ingress
인그레스 -
namespace
: 리소스에 대한 액세스를 허용할 Kubernetes 네임스페이스.kube-access
역할에서 우리는production
네임스페이스의 포드에 대한 액세스를 허용하고 있습니다. -
name
: 액세스를 허용할 포드의 이름.kube-access
에서 이는webapp
포드입니다. -
verbs
: 리소스에 대해 허용할 작업. 현재 텔레포트가 지원하는 작업은 다음과 같습니다:Verb Grants access to *
모든 작업 get
리소스 읽기 list
리소스 나열 create
리소스 생성 update
리소스 업데이트 patch
리소스 패치 delete
리소스 삭제 deletecollection
리소스 컬렉션 삭제 watch
리소스 감시 portforward
포트 포워딩 요청 생성 exec
포드에서 명령 실행
네임스페이스 및 이름 필드 모두에 와일드카드 문자(*
)를 추가하여 임의의 문자 시퀀스를 대체할 수 있습니다. 예를 들어, name: "pod-*-*"
는 pod-1-a
및 pod-2-c
로 명명된 포드와 일치합니다. kubernetes_labels
와 마찬가지로 값이 ^
로 시작하고 $
로 끝나는 경우 Kubernetes 서비스는 이를 Go의 re2
구문을 사용하는 정규 표현식으로 처리합니다(참고로 re2
README).
사용자가 역할의 kubernetes_resources
필드에 명시된 포드에 접근하기 위해서는 사용자가 최소한 kubernetes_groups
또는 kubernetes_users
에 하나의 값을 포함하는 텔레포트 역할을 할당받아야 합니다. 텔레포트는 액세스를 허용하거나 거부하도록 Kubernetes 역할을 변경하지 않습니다. 사용자가 클러스터에서 포드에 대한 액세스를 허용하거나 거부하도록 텔레포트 역할을 평가하는 방법에 대한 설명은 다음 섹션을 참조하세요.
Kubernetes 서비스가 텔레포트 역할을 평가하는 방법
텔레포트 사용자가 Kubernetes 클러스터의 API 서버에 요청을 보낼 때, 텔레포트 Kubernetes 서비스는 요청을 가로채고 사용자의 권한을 검사합니다. 사용자가 특정 리소스를 볼 수 있는 권한이 없으면 Kubernetes 서비스는 요청을 거부합니다. 사용자가 요청을 수행할 수 있는 권한이 있는 경우, Kubernetes 서비스는 요청을 수정하고 적절한 API 서버로 전달합니다.
사용자 요청 승인
텔레포트 Kubernetes 서비스는 요청을 수신하면 사용자 역할 내의 두 필드를 평가합니다. 이 필드 중 하나라도 사용자가 요청을 수행하도록 허용하지 않으면 Kubernetes 서비스는 사용자에게 오류를 반환합니다:
kubernetes_labels
텔레포트 Kubernetes 서비스는 포드가 실행 중인 클러스터에 사용자 kubernetes_labels
구성과 일치하는 레이블이 있는 경우에만 사용자가 포드에 대한 액세스를 허용합니다.
kubernetes_resources
Kubernetes API 서버 내의 일부 리소스 URI에는 특정 리소스의 이름이 포함되어 있습니다.
예를 들어, 사용자가 kubectl exec
를 실행하여 development
네임스페이스의 webapp
포드에 대한 명령을 실행하는 경우, kubectl
은 다음 경로로 대상 클러스터의 API 서버에 요청을 보냅니다:
"/api/v1/namespaces/development/pods/webapp/exec"
요청의 Kubernetes API 서버에 대한 URL 경로에 Kubernetes 포드가 있는 경우, 텔레포트 Kubernetes 서비스는 사용자가 해당 포드에 액세스할 수 있는 권한이 있는지 확인합니다.
예를 들어, 위의 예에서 Kubernetes 서비스는 사용자가 development
네임스페이스에 있는 webapp
포드에 접근할 수 있는 권한이 있는지 확인하고, 없으면 요청을 거부합니다.
사용자 요청 전달
텔레포트 Kubernetes 서비스가 사용자가 Kubernetes 클러스터에 대한 요청을 수행할 수 있는지 검사하고 특정 리소스(해당되는 경우)에 대해 권한을 부여하면, 요청을 상위 API 서버로 조립합니다. 사용자 역할의 kubernetes_groups
및 kubernetes_users
필드에 따라 임시화 헤더를 요청에 추가합니다 (이 필드에 대한 논의 참조).
텔레포트 Kubernetes 서비스는 위에서 생성된 임시화 헤더에서 지정된 RBAC 원칙을 사용하여 상위 API 서버에 접근하므로, 이러한 필드에 지정한 원칙은 사용자가 kubernetes_resources
필드의 리소스에 접근해야 합니다. 그렇지 않으면 Kubernetes 서비스는 올바르지 않은 권한으로 상위 API 서버에 대한 요청을 전달하고 API 서버는 요청을 거부합니다.
여러 역할
Kubernetes 서비스가 여러 역할을 평가하는 방법
텔레포트 Kubernetes 서비스는 사용자의 요청을 Kubernetes API 서버에 평가하기 전에 사용자의 역할을 확인합니다. 하나의 역할의 spec.allow.kubernetes_labels
또는 spec.allow.kubernetes_resources
조건이 사용자의 요청과 일치하지 않으면 Kubernetes 서비스는 다음 역할을 확인합니다.
Kubernetes 서비스가 클러스터의 레이블 및 요청의 리소스와 모두 일치하는 spec.allow
조건을 가진 역할을 발견하면, 해당 역할의 allow.kubernetes_groups
및 allow.kubernetes_users
필드를 조회합니다. 이 값을 나중에 임시화 헤더를 작성하는 데 사용할 RBAC 원칙 목록에 추가합니다.
그 다음, Kubernetes 서비스는 사용자의 역할에서 spec.deny
조건을 확인합니다. 하나의 역할의 spec.deny.kubernetes_labels
또는 spec.deny.kubernetes_resources
필드가 사용자의 요청과 일치하는 경우, Kubernetes 서비스는 해당 역할의 spec.deny.kubernetes_groups
및 spec.deny.kubernetes_users
필드를 조회합니다. 이 값을 이전에 생성한 사용자 및 그룹 목록에서 제거하여 이러한 RBAC 원칙에 대한 액세스를 거부합니다.
예
사용자에게 다음 세 가지 역할이 할당되었다고 가정해 보겠습니다:
kind: role
metadata:
name: allow-dev-us-east-2
version: v7
spec:
allow:
kubernetes_labels:
- "region": "us-east-2"
kubernetes_resources:
- kind: pod
namespace: "development"
name: "redis-*"
- kind: pod
namespace: "development"
name: "nginx-*"
kubernetes_groups:
- dev-viewers # 개발 네임스페이스에서 포드를 볼 수 있도록 사용자를 허용합니다.
---
kind: role
metadata:
name: allow-exec
version: v7
spec:
allow:
kubernetes_labels:
- "*": "*"
kubernetes_resources:
- kind: pod
namespace: "*"
name: "*"
kubernetes_groups:
- executors # 사용자가 임의의 포드에 대해 명령을 실행할 수 있도록 허용합니다.
---
kind: role
metadata:
name: deny-redis-exec
version: v7
spec:
deny:
kubernetes_resources:
- kind: pod
namespace: "*"
name: "redis-*"
kubernetes_groups:
- executors
dev-viewers
Kubernetes 그룹은 사용자가 development
네임스페이스의 포드를 볼 수 있게 합니다. executors
Kubernetes 그룹은 사용자가 어떤 네임스페이스의 모든 포드에 대해서도 명령을 실행할 수 있도록 허용합니다.
사용자가 kubectl get pods/redis-1
을 development
네임스페이스에서 실행하고 클러스터에 레이블 region:us-east-2
가 있다면, Kubernetes 서비스는 요청을 수락합니다. deny-redis-exec
역할이 redis-*
포드에 대해 executors
그룹을 거부하므로, Kubernetes 서비스는 dev-viewers
그룹을 임시화하면서 요청을 전달하지만 executors
그룹은 임시화하지 않습니다.
그러나 동일한 사용자가 development
네임스페이스에서 kubectl exec -it nginx /bin/bash
를 실행하면 Kubernetes 서비스는 요청을 dev-viewers
및 executors
그룹 모두를 임시화하여 전달합니다. 요청에 대한 deny-redis-exec
역할의 deny
조건이 일치하지 않기 때문입니다.
리소스에 대한 점진적 액세스 활성화
텔레포트 및 Kubernetes RBAC를 설계하여 사용자에게 Kubernetes 리소스의 제한된 하위 집합에 대한 액세스를 점진적으로 허용할 수 있습니다. 즉, 사용자는 Kubernetes 클러스터의 광범위한 리소스에 대한 제한된 액세스가 가능하며, 더 제한된 리소스에 대한 더 높은 액세스를 갖는 여러 사용자 그룹을 생성할 수 있습니다.
이렇게 하려면 여러 텔레포트 역할을 정의하십시오:
- 일부 역할은 더 많은 Kubernetes 리소스에 대한 더 낮은 액세스 권한을 부여합니다.
- 다른 역할은 더 적은 Kubernetes 리소스에 대해 더 높은 권한을 부여합니다.
그 후, 서로 다른 사용자에게 조합된 역할을 할당할 수 있습니다.
예를 들어, 이 역할 조합은 사용자가 모든 등록된 Kubernetes 클러스터의 모든 포드를 볼 수 있도록 하지만 nginx-*
포드에서만 kubectl exec
또는 kubectl logs
를 실행할 수 있게 합니다:
kind: role
metadata:
name: kube-viewer
version: v7
spec:
allow:
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: pod
namespace: "*"
name: "*"
kubernetes_groups:
- viewer # 포드를 가져오고 나열할 수 있지만 명령을 실행하거나 로그를 검색할 수는 없습니다.
---
kind: role
metadata:
name: nginx-exec
version: v7
spec:
allow:
kubernetes_labels:
'*': '*'
kubernetes_resources:
- kind: pod
namespace: "*"
name: "nginx-*"
kubernetes_groups:
- execAndLogs
이 경우 kube-viewer
역할은 사용자를 Kubernetes viewer
그룹에 매핑하여 사용자가 포드를 가져오고 나열할 수 있지만 명령을 실행하거나 로그를 검색할 수 없습니다. nginx-exec
역할을 통해 사용자는 execAndLogs
그룹에 접근할 수 있으며, 오로지 nginx
포드에 대해서만 명령을 실행하고 로그를 검색할 수 있습니다.
이 설정에서는 kube-viewer
역할을 다른 역할과 결합하여 사용자의 요구 사항에 따라 포드의 하위 집합에 대한 높은 권한을 부여할 수 있습니다.
보안 고려사항: 리소스 네임스페이스 제한
텔레포트 사용자가 포드 목록을 가져오기 위해 요청을 보낼 때, 예를 들어 kubectl get pods
, 텔레포트 Kubernetes 서비스는 다음을 수행합니다:
- 사용자 텔레포트 역할의 임시화 헤더를 추가하여 상위 Kubernetes API 서버에서 사용 가능한 포드를 검색합니다. 이는 사용자가 보낸 요청의 임시화 헤더에 Kubernetes 사용자 및 그룹이 포함됩니다.
- 사용자가
kubernetes_resources
를 통해 액세스할 수 있는 포드로 목록을 필터링합니다. - 사용자가 지정한 포드 목록을 반환합니다.
리소스가 우발적으로 노출되지 않도록 하려면, Kubernetes RBAC에 설정한 네임스페이스 제한이 텔레포트에 설정한 제한과 일치하는지 확인해야 합니다.
예를 들어, 사용자가 모든 네임스페이스의 모든 포드에 대한 액세스를 허용하는 텔레포트 역할을 가지고 있으며 이 사용자가 default-pod-viewer
Kubernetes 그룹에 매핑되어 있을 경우, 이 그룹은 default
네임스페이스의 포드만 볼 수 있습니다:
kind: role
metadata:
name: kube-access-1
version: v7
spec:
allow:
kubernetes_groups:
- default-pod-viewer
kubernetes_resources:
- kind: pod
namespace: "*"
name: "*"
# ...
이 사용자에게 두 번째 텔레포트 역할이 있으며, 이 사용자를 system:masters
Kubernetes 그룹(모든 네임스페이스의 모든 포드에 접근할 수 있음)으로 매핑하고 default
네임스페이스에서 webapp
포드에 대한 액세스만 허용합니다:
metadata:
name: kube-access-2
version: v7
spec:
allow:
kubernetes_groups:
- system:masters
kubernetes_resources:
- kind: pod
namespace: "default"
name: "webapp"
# ...
그 사용자에게 system:masters
에 매핑된 역할(kube-access-2
)이 있으므로, Kubernetes 서비스는 이 사용자의 요청을 처리하면서 모든 포드 목록을 가져올 수 있습니다. 그러나 사용자가 kube-access-1
역할을 가지고 있다면 모든 네임스페이스의 포드 목록이 노출됩니다.
리소스에 대한 접근이 노출되지 않도록 하려면 Kubernetes에서 자체적으로 지정한 권한과 텔레포트가 특정 사용자에게 지정한 권한 간에 제한을 설정해야 합니다.