쿠버네티스 RBAC는 클러스터 사용자나 워크로드가 역할을 수행하기 위해 필요한 자원에 대한 접근 권한을 통제하는 핵심 보안 제어 방식으로 기본 권한 관리 방법이다.
유저가 클러스터에 명령을 날릴때 kubectl명령으로 사용하게 되는데
.kube/config파일에 클러스터와 유저 내용이 리스트 형태( -로 구분 )로 적혀있고
클러스터와 유저를 매핑한 context를 생성해두면 특정 클러스터의 특정 유저로 접근이 가능하다.
- 현재 사용중인 context는 currunt-context로 알 수 있다.
- 같은 계정을 공유하는 환경이면 서로 다른 context를 사용하거나 수정하면 에러나 충돌이 발생할 수 있다.
- kubectl config get-contexts 명령어로 현재 사용중인 context를 확인할 수 있으며 kubectl config use-context <context명> 으로 사용할 context를 변경할 수 있다.
쿠버네티스는 네임스페이스 단위에서 유저 리소스 접근을 핸들링하기 위한 4가지 접근 제어 방식이 존재한다.
- Node : 스케줄링 된 파드의 kubelet에서 접근 제어
- ABAC : 속성 기반 접근 제어
- RBAC : 역할 기반 접근 제어
- Webhook : POST 요청에 대한 접근 제어
- RBAC은 특정 역할을 API 엔드포인트로 연결할 때 API 서버와 통신하는 API 그룹으로 관련 기능 요청을 수집한다.
- RBAC는 rbac.authorization.k8s.io API를 사용한다.
- ABAC처럼 마스터에 접근할 필요 없이 kubectl이나 API를 이용해 관리할 수 있다.
롤(Role)
특정 API나 리소스 등 파일에 명시해둔 규칙의 집합이 되며, 특정 네임스페이스에 대한 권한을 관리한다.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: test-pod-reader
rules:
- apiGroups: [""] # 핸들링할 API가 포함된 그룹
resources: ["pods"] # 핸들링할 API 종류
verbs: ["get", "watch", "list"] # 핸들링하고자 하는 액션
resourceNames: ["pod-A", "pod-B"] # 핸들링을 허용하는 리소스
# resourceNames필드를 설정하면 설정된 자원에만 적용되며, create, watch, list 등의
# rules[].verb 필드 값은 적용되지 않는다.
- apiGroups: ["apps"]
resources: ["deployment"]
verbs: ["create", "list"]
롤바인딩(RoleBinding)
롤바인딩은 롤과 특정 사용자를 묶어주는 역할을 수행하고, 지정한 사용자들에 한해서 롤에 명시한 규칙들을 기준으로 권한을 사용할 수 있도록 관리를 할 수 있다.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects: # 롤을 적용할 유저
- kind: User or Group or ServiceAccount
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef: # 유저에게 적용할 롤
kind: Role
name: test-pod-reader
apiGroup: rbac.authorization.k8s.io
RBAC 핸들링
롤 목록 확인 : kubectl get role
롤 상세 정보 확인 : kubectl describe role [롤_이름]
롤 바인딩 목록 확인 : kubectl get rolebindings
롤 바인딩 상세 정보 확인 : kubectl describe rolebindings [롤바인딩_이름]
권한 가능 여부 확인 : kubectl auth can-i [액션] [리소스] --as [유저]
클러스터롤(ClusterRole) & 클러스터롤바인딩(ClusterRoleBinding)
클러스터롤과 클러스터롤바인딩을 사용해야 하고 1:N 연결이 가능하다. (클러스터롤과 클러스터롤바인딩은 admin 계정으로만 확인 가능)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects: # 롤을 적용할 유저
- kind: User or Group or ServiceAccount # 유저 또는 그룹 지정
name: michelle
apiGroup: rbac.authorization.k8s.io
roleRef: # 유저에게 적용할 롤
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
APP(pod) - Service Account - Rolebinding - Role
kubectl describe rolebinding <rolebinding name> -n <namespace> 하면 특정 롤바인딩에서 명시한 Service Account를 확인할 수 있다, Service Account는 어느 Rolebinding을 가르키는게 아니라 Rolebinding이 Service Account를 가리키는 방식
파드 정의의 spec.serviceAccountName 필드에 Service Account의 이름을 명시하여 할당할 수 있다. 서비스어카운트는 반드시 파드가 생성될 때 지정해야 한다. 그 이후에는 변경할 수 없다.
apiVersion: v1
kind: Pod
metadata:
name: curl-custom-sa
spec:
serviceAccountName: foo # default 대신 다른 서비스 어카운트 사용
containers:
- name: main
image: tutum/curl
command: ["sleep", "9999999"]
- name: ambassador
image: luksa/kubectl-proxy:1.6.2
Rolebinding의 YAML
$ kubectl edit rolebinding test -n foo yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: test
namespace: foo
roleRef: # 롤바인딩은 service-reader 룰을 참조
apiGroup: rbac.authorization.k8s.io
kind: Role
name: service-reader
subjects: # foo 네임스페이스상에서 default 서비스어카운트에 바인드
- kind: ServiceAccount
name: default
namespace: foo
- kind: ServiceAccount
name: default
namespace: bar
적용중인 접근제어 종류 확인
vi /etc/kubernetes/manifests/kube-apiserver.yaml 파일의
authorization-mode 부분 확인
ClusterRole 핸들링
클러스터롤 목록 확인 : kubectl get clusterrole
클러스터롤 상세 정보 확인 : kubectl describe clusterrole [클러스터롤_이름]
클러스터롤 바인딩 목록 확인 : kubectl get clusterrolebindings
클러스터롤 바인딩 상세 정보 확인 : kubectl describe clusterrolebindings [클러스터롤바인딩_이름]
권한 가능 여부 확인 : kubectl auth can-i [액션] [리소스] --as [유저]
Error from server (Forbidden) : 는 해당 사용자에게 권한이 없다는 에러
바인딩 타입
접근 | 롤 타입 | 바인딩 타입 |
클러스터 수준 리소스 (노드, 영구 볼륨) |
clusterrole | clusterrolebinding |
비리소스 URL (/api, /healthz, ...) |
clusterrole | clusterrolebinding |
여러 네임스페이스에 있는 네임스페이스 리소스 (그리고 모든 네임스페이스에 걸쳐있는) |
clusterrole | clusterrolebinding |
특정 네임스페이스에 있는 네임스페이스 리소스 (다수의 네임스페이스에 동일한 클러스터를 재사용) |
clusterrole | rolebinding |
특정 네임스페이스에 있는 네임스페이스 리소스 (롤은 각 네임스페이스에서 정의) |
role | rolebinding |
모범 사례
최소 권한
- 작업에 명시적으로 필요한 권한만 부여되어야 한다.
- 권한은 가능하면 네임스페이스 레벨에서 부여하고 특정 네임스페이스 내에서만 사용자에게 권한을 부여한다.
- 운영자는 cluster-admin 계정이 필수로 요구되지 않을시에는 사용을 지양한다.
- system:master그룹에 사용자 추가를 지양한다.
특정 토큰 분배 최소화
- 강력한 권한이 부여된 서비스 어카운트를 파드에게 지정해서는 안된다.
- 강력한 권한이 부여된 파드를 외부로 노출된 파드와 함께 실행하는 것을 지양한다.
하드닝(Hardening)
system:unauthenticated 그룹의 바인딩은 누구에게나 네트워크 레벨에서 API 서버와 통신할 수 있는 권한을 부여하므로 가능하면 제거한다.
주기적 검토
쿠버네티스 RBAC 설정을 주기적으로 검토해야한다. 만일 공격자가 삭제된 사용자와 같은 이름으로 사용자 계정을 생성할 수 있다면, 삭제된 사용자의 모든 권한, 특히 해당 사용자에게 부여되었던 권한까지도 자동으로 상속받을 수 있게 된다
참고 : https://velog.io/@niyu, https://kuberetes.io/ko/docs/concepts/security/rbac-god-practices/
'Docker & Kubenetes' 카테고리의 다른 글
쿠버네티스 파드 네트워킹 (0) | 2023.09.06 |
---|---|
쿠버네티스 볼륨 PV 와 PVC (0) | 2023.09.04 |
쿠버네티스 서비스와 인그레스(SVC, Ingress) (0) | 2023.08.21 |
쿠버네티스 클러스터 컴포넌트 Kubernetes Cluster Component (0) | 2023.08.02 |
Kubernetes 트러블 슈팅의 기본 프로세스 (0) | 2023.07.22 |