역할 기반 접근 제어(RBAC) 모범 사례

역할 기반 접근 제어(RBAC) 모범 사례 (Role Based Access Control Good Practices)

쿠버네티스 RBAC는 클러스터 사용자와 워크로드가 자신의 역할을 수행하는 데 필요한 리소스에만 접근할 수 있도록 보장하는 핵심 보안 제어예요. 클러스터 사용자를 위한 권한을 설계할 때, 클러스터 관리자가 권한 상승(privilege escalation)이 발생할 수 있는 영역을 이해하는 것은 과도한 접근이 보안 사고로 이어지는 위험을 줄이기 위해 중요해요.

여기에 설명된 모범 사례는 일반적인 RBAC 문서와 함께 읽어야 해요.

출처: 문서

본문

일반적인 모범 사례 (General good practice)

최소 권한 (Least privilege)

이상적으로는 사용자와 서비스 계정에 최소한의 RBAC 권한이 할당되어야 해요. 운영에 명시적으로 필요한 권한만 사용해야 해요. 각 클러스터는 다르지만, 적용할 수 있는 몇 가지 일반 규칙이 있어요.

  • 가능하면 네임스페이스 수준에서 권한을 할당하세요. 사용자에게 특정 네임스페이스 안에서만 권한을 주려면 ClusterRoleBindings 대신 RoleBindings를 사용하세요.
  • 가능하면, 특히 모든 리소스에 대해, 와일드카드 권한 제공을 피하세요. 쿠버네티스는 확장 가능한 시스템이므로, 와일드카드 접근은 클러스터에 현재 존재하는 모든 객체 유형뿐 아니라 미래에 생성될 모든 객체 유형에도 권한을 부여해요.
  • 관리자는 특별히 필요할 때를 제외하고 cluster-admin 계정을 사용하지 말아야 해요. 낮은 권한의 계정에 가장(impersonation) 권한을 제공하면 클러스터 리소스의 우발적인 수정을 피할 수 있어요.
  • 사용자를 system:masters 그룹에 추가하지 마세요. 이 그룹의 구성원인 사용자는 모든 RBAC 권한 검사를 우회하고 항상 제한 없는 슈퍼유저 접근을 가지며, RoleBindings나 ClusterRoleBindings를 제거해도 되돌릴 수 없어요. 덧붙여, 클러스터가 권한 부여 웹훅(authorization webhook)을 사용한다면 이 그룹의 구성원은 그 웹훅도 우회해요(그 그룹의 사용자의 요청은 웹훅에 결코 보내지지 않아요).

권한 있는 토큰의 배포 최소화

이상적으로 파드에는 강력한 권한이 부여된(예: 아래의 권한 상승 위험에 나열된 권한 중 어떤 것이든) 서비스 계정이 할당되지 않는 것이 좋아요. 워크로드에 강력한 권한이 필요한 경우 다음 관행을 고려하세요.

  • 강력한 파드를 실행하는 노드 수를 제한하세요. 실행하는 모든 DaemonSet이 필요하고 최소 권한으로 실행되어 컨테이너 이스케이프의 폭발 반경(blast radius)을 제한하도록 보장하세요.
  • 강력한 파드를 신뢰할 수 없거나 공개적으로 노출된 파드 옆에서 실행하지 마세요. 테인트와 톨러레이션(Taints and Toleration), NodeAffinity, 또는 PodAntiAffinity를 사용해 파드가 신뢰할 수 없거나 덜 신뢰되는 파드 옆에서 실행되지 않도록 보장하세요. 덜 신뢰되는 파드가 restricted 파드 보안 표준을 충족하지 못하는 상황에 특히 주의하세요.

강화 (Hardening)

쿠버네티스는 모든 클러스터에서 필요하지 않을 수 있는 접근을 기본으로 제공해요. 기본으로 제공되는 RBAC 권한을 검토하면 보안 강화 기회를 제공할 수 있어요. 일반적으로 system: 계정에 제공된 권한에 변경을 가해서는 안 됩니다. 클러스터 권한을 강화하기 위한 몇 가지 옵션이 있어요.

  • system:unauthenticated 그룹에 대한 바인딩을 검토하고 가능하면 제거하세요. 이는 네트워크 수준에서 API 서버에 접근할 수 있는 누구에게나 접근을 주기 때문이에요.
  • automountServiceAccountToken: false를 설정해 서비스 계정 토큰의 기본 자동 마운트를 피하세요. 자세한 내용은 기본 서비스 계정 토큰 사용을 참고하세요. 파드에 대해 이 값을 설정하면 서비스 계정 설정을 덮어쓰며, 서비스 계정 토큰이 필요한 워크로드는 여전히 마운트할 수 있어요.

주기적인 검토 (Periodic review)

주기적으로 쿠버네티스 RBAC 설정을 중복 항목과 가능한 권한 상승에 대해 검토하는 것이 중요해요. 공격자가 삭제된 사용자와 같은 이름의 사용자 계정을 만들 수 있다면, 삭제된 사용자의 모든 권한, 특히 그 사용자에게 할당된 권한을 자동으로 상속할 수 있어요.

쿠버네티스 RBAC - 권한 상승 위험 (privilege escalation risks)

쿠버네티스 RBAC에는 권한이 부여되면 사용자나 서비스 계정이 클러스터에서 권한을 상승시키거나 클러스터 밖의 시스템에 영향을 줄 수 있는 여러 권한이 있어요.

이 섹션은 클러스터 운영자가 주의를 기울여야 하는 영역을 가시화하여, 의도치 않게 의도보다 클러스터에 더 많은 접근을 허용하지 않도록 하기 위한 것이에요.

Secret 나열하기 (Listing secrets)

일반적으로 Secrets에 대한 get 접근을 허용하면 사용자가 그 내용을 읽을 수 있다는 것은 명확해요. listwatch 접근도 효과적으로 사용자가 Secret 내용을 드러낼 수 있다는 점을 주목하는 것도 중요해요. 예를 들어 List 응답이 반환될 때(kubectl get secrets -A -o yaml 같은), 그 응답에는 모든 Secret의 내용이 포함돼요.

워크로드 생성 (Workload creation)

네임스페이스에서 워크로드(파드 또는 파드를 관리하는 워크로드 리소스)를 생성할 권한은 그 네임스페이스의 많은 다른 리소스(파드에 마운트될 수 있는 Secrets, ConfigMaps, PersistentVolumes 같은)에 대한 접근을 암묵적으로 부여해요. 추가로, 파드는 어떤 ServiceAccount로든 실행될 수 있으므로, 워크로드 생성 권한을 부여하는 것은 그 네임스페이스의 어떤 서비스 계정의 API 접근 수준도 암묵적으로 부여해요.

권한 있는(privileged) 파드를 실행할 수 있는 사용자는 그 접근을 사용해 노드 접근을 얻고 잠재적으로 자신의 권한을 더 높일 수 있어요. 사용자나 다른 주체가 적절히 안전하고 격리된 파드를 만들 능력을 완전히 신뢰하지 않는다면, baseline 또는 restricted 파드 보안 표준을 강제해야 해요. 파드 보안 어드미션(Pod Security admission) 또는 다른 (서드파티) 메커니즘을 사용해 그 강제를 구현할 수 있어요.

이러한 이유로 서로 다른 신뢰 또는 임대(tenancy) 수준이 필요한 리소스를 분리하기 위해 네임스페이스를 사용해야 해요. 최소 권한 원칙을 따르고 최소한의 권한 집합을 할당하는 것이 여전히 모범 사례로 간주되지만, 네임스페이스 안의 경계는 약한 것으로 간주해야 해요.

영구 볼륨 생성 (Persistent volume creation)

누군가 또는 어떤 애플리케이션이 임의의 PersistentVolume을 만들 수 있다면, 그 접근은 hostPath 볼륨의 생성도 포함하며, 이는 파드가 해당 노드의 기반 호스트 파일시스템에 접근하게 된다는 뜻이에요. 그 능력을 부여하는 것은 보안 위험이에요.

호스트 파일시스템에 제한 없는 접근을 가진 컨테이너가 권한을 상승시킬 수 있는 방법은 많아요. 다른 컨테이너의 데이터 읽기, Kubelet 같은 시스템 서비스의 자격 증명 남용 등이에요.

PersistentVolume 객체를 생성할 접근은 다음에게만 허용해야 해요.

  • 작업에 이 접근이 필요하고 신뢰하는 사용자(클러스터 운영자).
  • 자동 프로비저닝을 위해 구성된 PersistentVolumeClaim을 기반으로 PersistentVolume을 만드는 쿠버네티스 제어 플레인 구성 요소. 이는 보통 CSI 드라이버를 설치할 때 쿠버네티스 제공자 또는 운영자가 설정해요.

영구 저장소에 대한 접근이 필요한 곳에서는 신뢰할 수 있는 관리자가 PersistentVolume을 만들고, 제한된 사용자는 그 저장소에 접근하기 위해 PersistentVolumeClaim을 사용해야 해요.

노드의 proxy 하위 리소스에 대한 접근

nodes/proxy 하위 리소스에 접근할 수 있는 사용자는 Kubelet API에 대한 권한을 가지며, 이는 권한이 있는 노드의 모든 파드에서 명령 실행을 가능하게 해요. 이 접근은 감사 로깅과 어드미션 컨트롤을 우회하므로, 이 리소스에 어떤 권한을 부여하기 전에 주의해야 해요. 이러한 API는 웹소켓 HTTP GET 요청을 통해 실행될 수 있으며, 이는 get 동사의 권한 부여만 필요해요. 즉 nodes/proxy에 대한 get 권한은 읽기 전용 권한이 아니에요. 예를 들어 nodes/proxy를 get할 권한은 호출자가 쿠버네티스 API를 통한 동등한 권한이 없더라도 컨테이너 로그를 검색하거나 파드 프로세스에 실행·연결할 수 있는 권한 있는 kubelet API에 대한 접근을 제공해요.

자세한 내용은 Kubelet 인증/권한 부여를 참고하세요.

Escalate 동사

일반적으로 RBAC 시스템은 사용자가 가진 권리보다 더 많은 권리를 가진 clusterrole을 만드는 것을 방지해요. 이에 대한 예외는 escalate 동사예요. RBAC 문서에 언급된 대로, 이 권한이 있는 사용자는 효과적으로 자신의 권한을 상승시킬 수 있어요.

Bind 동사

escalate 동사와 유사하게, 사용자에게 이 권한을 부여하면 권한 상승에 대한 쿠버네티스 내장 보호를 우회할 수 있어, 사용자가 자신이 가지지 않은 권리를 가진 역할에 대한 바인딩을 만들 수 있게 해요.

Impersonate 동사

이 동사는 사용자가 클러스터의 다른 사용자를 가장하고 그 권한을 얻을 수 있게 해요. 부여할 때 주의해야 하며, 가장된 계정 중 하나를 통해 과도한 권한을 얻을 수 없도록 해야 해요.

CSR과 인증서 발급

CSR API는 certificatesigningrequests/approval에 대한 create 권한과, 서명자가 kubernetes.io/kube-apiserver-client인 곳에 대한 update 권한을 가진 사용자가, 사용자가 클러스터에 인증할 수 있는 새 클라이언트 인증서를 만들 수 있게 해줘요. 그 클라이언트 인증서는 쿠버네티스 시스템 구성 요소의 중복을 포함한 임의의 이름을 가질 수 있어요. 이는 효과적으로 권한 상승을 허용해요.

토큰 요청 (Token request)

serviceaccounts/token에 대한 create 권한이 있는 사용자는 기존 서비스 계정에 대한 토큰을 발급하기 위해 TokenRequest를 만들 수 있어요.

어드미션 웹훅 제어

validatingwebhookconfigurations 또는 mutatingwebhookconfigurations를 제어할 수 있는 사용자는 클러스터에 어드미션되는 어떤 객체든 읽을 수 있는 웹훅을 제어할 수 있으며, mutating 웹훅의 경우 어드미션되는 객체를 변경할 수도 있어요.

네임스페이스 수정 (Namespace modification)

Namespace 객체에서 patch 작업을 수행할 수 있는 사용자(그 접근을 가진 Role에 대한 네임스페이스 스코프 RoleBinding을 통해)는 그 네임스페이스의 라벨을 수정할 수 있어요. 파드 보안 어드미션(Pod Security Admission)이 사용되는 클러스터에서 이는 사용자가 관리자가 의도한 것보다 더 관대한 정책으로 네임스페이스를 구성할 수 있게 할 수 있어요. NetworkPolicy가 사용되는 클러스터에서 사용자는 관리자가 허용하려는 의도가 없는 서비스에 간접적으로 접근할 수 있게 하는 라벨을 설정할 수 있어요. 동적 리소스 할당(Dynamic Resource Allocation)을 사용하는 클러스터에서 resource.kubernetes.io/admin-access: "true"로 네임스페이스에 라벨을 지정하면, 그 네임스페이스에서 ResourceClaim을 만들 수 있는 어떤 사용자든 어떤 네임스페이스의 다른 어떤 클레임에 이미 할당된 장치에 관리자 접근을 요청할 수 있게 해요.

쿠버네티스 RBAC - 서비스 거부(DoS) 위험 (denial of service risks)

객체 생성 서비스 거부 (Object creation denial-of-service)

클러스터에서 객체를 만들 권리가 있는 사용자는, 쿠버네티스가 사용하는 etcd가 OOM 공격에 취약하다는 것에서 논의된 것처럼, 객체의 크기나 수에 기반해 서비스 거부 조건을 만들 만큼 충분히 큰 객체를 만들 수 있어요. 이는 반 신뢰 또는 신뢰하지 않는 사용자에게 시스템에 제한된 접근이 허용되는 멀티 테넌트 클러스터에서 특히 관련이 있을 수 있어요.

이 문제의 완화 옵션 중 하나는 생성할 수 있는 객체의 양을 제한하기 위해 리소스 할당량(resource quotas)을 사용하는 것이에요.

더 알아보기 (Learn more)

  • RBAC에 대해 더 배우려면 RBAC 문서를 참고하세요.