LabHub
배우기 러닝패스 코스

Kubernetes Operations

Designing Roles With Least Privilege

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

역할과 바인딩을 직접 만들어 최소 권한을 설계하고, kubectl auth can-i 로 권한의 경계를 검증하는 습관을 들입니다.

왜 중요한가

RBAC 에서 사람들이 가장 많이 헷갈리는 지점은 스코프를 정하는 것이 역할이 아니라 바인딩이라는 사실입니다. 같은 ClusterRole 이라도 ClusterRoleBinding 으로 걸면 클러스터 전체, RoleBinding 으로 걸면 그 네임스페이스에서만 유효합니다. 이 성질 덕분에 공통 권한 묶음을 ClusterRole 로 한 번만 정의하고 팀마다 자기 네임스페이스에서 재사용할 수 있습니다. 두 번째 함정은 서브리소스입니다. podspods/log, pods/exec 는 서로 다른 리소스 이름이라 권한이 자동으로 따라오지 않습니다. 로그만 읽는 봇에게 셸 접속 권한까지 딸려 가지 않게 하려면 이 구분이 필요합니다. 마지막으로 권한은 작성하는 것이 아니라 판정되는 것이므로, 매니페스트를 눈으로 읽는 대신 impersonation 으로 물어보세요. yes 만 확인하지 말고 no 도 함께 확인해야 권한이 필요 이상으로 넓은지 알 수 있습니다.

단계

  1. 네임스페이스 rbac-lab 을 만들고 그 안에 서비스 어카운트 app-reader, inspector, log-bot 세 개를 만드세요.
  2. rbac-lab 에 Role pod-reader 를 만드세요. 규칙은 하나이며 apiGroups 는 코어 그룹(빈 문자열), resourcespods, verbsget, list, watch 세 개입니다. 와일드카드 * 는 어디에도 쓰면 안 됩니다.
  3. rbac-lab 에 RoleBinding read-pods 를 만드세요. roleRef 는 kind Role, name pod-reader 이고, 주체는 kind ServiceAccount, name app-reader, namespace rbac-lab 입니다.
  4. app-reader 로 impersonation 해서 권한을 확인하고 결과를 /root/ops/rbac/out/can-i.txt 에 저장하세요. 이 파일에는 yes 응답과 no 응답이 모두 들어 있어야 합니다. 확인할 항목은 최소한 다음 셋입니다 — rbac-lab 에서 파드 목록 조회(yes), rbac-lab 에서 파드 삭제(no), default 네임스페이스에서 파드 목록 조회(no).
  5. ClusterRole node-viewer 를 만드세요. resourcesnodes 가 들어가고 모든 규칙의 verbsget, list, watch 뿐이어야 합니다. 이어서 ClusterRoleBinding node-viewer-binding 으로 이 역할을 rbac-labapp-reader 에게 주세요. 결과적으로 app-reader 는 노드를 조회할 수 있고 삭제할 수는 없어야 합니다.
  6. ClusterRole ns-inspector 를 만드세요(ConfigMap 을 읽을 수 있어야 합니다). 그리고 rbac-lab 에 RoleBinding inspect-here 를 만들어 roleRef.kindClusterRole, name 을 ns-inspector 로 하고 주체는 rbac-labinspector 로 하세요. 결과적으로 inspectorrbac-lab 에서는 ConfigMap 을 읽지만 default 에서는 읽지 못해야 합니다.
  7. rbac-lab 에 Role log-reader 를 만드세요. resources 에는 pods/log 만 넣고 pods넣지 마세요. 이 역할을 log-bot 에게 RoleBinding 으로 거세요. 결과적으로 log-botpods/log 를 읽을 수 있고, pods 자체는 읽지 못하며, pods/exec 도 쓰지 못해야 합니다.
  8. /root/ops/rbac/out/rbac-audit.json 을 만드세요. 필드는 네 개입니다. cluster_admin_bindingsroleRef.namecluster-admin 인 ClusterRoleBinding 이름 배열이며 실제 클러스터의 개수와 정확히 일치해야 하고 기본 바인딩인 cluster-admin 이 포함돼야 합니다. wildcard_roles* 를 쓰는 역할 이름 배열(1개 이상), secret_readerssecrets 를 다루는 역할 이름 배열(1개 이상), least_privilege_violations 는 최소 권한 위반으로 판단한 항목 배열입니다.

참고

네임스페이스와 서비스 어카운트 준비하기

네임스페이스 rbac-lab 을 만들고 그 안에 서비스 어카운트 app-reader, inspector, log-bot 세 개를 만드세요.

주체가 있어야 권한을 줄 수 있습니다. 서비스 어카운트는 네임스페이스에 속하며 이름만으로 만들 수 있습니다.

읽기 전용 Role 만들기

rbac-lab 에 Role pod-reader 를 만드세요. 규칙은 하나이며 apiGroups 는 코어 그룹(빈 문자열), resourcespods, verbsget, list, watch 세 개입니다. 와일드카드 * 는 어디에도 쓰면 안 됩니다.

코어 리소스의 API 그룹 이름이 무엇인지 확인하세요. 읽기 셋은 세 개이고 와일드카드는 쓰지 않습니다.

Role 을 서비스 어카운트에 바인딩하기

rbac-lab 에 RoleBinding read-pods 를 만드세요. roleRef 는 kind Role, name pod-reader 이고, 주체는 kind ServiceAccount, name app-reader, namespace rbac-lab 입니다.

주체가 서비스 어카운트일 때는 이름만으로 부족합니다. 어느 네임스페이스의 어카운트인지까지 적어야 합니다.

impersonation 으로 권한 경계 확인하기

app-reader 로 impersonation 해서 권한을 확인하고 결과를 /root/ops/rbac/out/can-i.txt 에 저장하세요. 이 파일에는 yes 응답과 no 응답이 모두 들어 있어야 합니다. 확인할 항목은 최소한 다음 셋입니다 — rbac-lab 에서 파드 목록 조회(yes), rbac-lab 에서 파드 삭제(no), default 네임스페이스에서 파드 목록 조회(no).

서비스 어카운트의 정식 이름 형식을 기억하세요. 되는 것과 안 되는 것을 모두 확인해야 경계가 드러납니다.

클러스터 범위 리소스용 ClusterRole 만들기

ClusterRole node-viewer 를 만드세요. resourcesnodes 가 들어가고 모든 규칙의 verbsget, list, watch 뿐이어야 합니다. 이어서 ClusterRoleBinding node-viewer-binding 으로 이 역할을 rbac-labapp-reader 에게 주세요. 결과적으로 app-reader 는 노드를 조회할 수 있고 삭제할 수는 없어야 합니다.

노드는 네임스페이스가 없는 리소스라 Role 로는 다룰 수 없습니다. 클러스터 전체에 걸려면 바인딩도 클러스터 범위여야 합니다.

ClusterRole 을 RoleBinding 으로 걸어 보기

ClusterRole ns-inspector 를 만드세요(ConfigMap 을 읽을 수 있어야 합니다). 그리고 rbac-lab 에 RoleBinding inspect-here 를 만들어 roleRef.kindClusterRole, name 을 ns-inspector 로 하고 주체는 rbac-labinspector 로 하세요. 결과적으로 inspectorrbac-lab 에서는 ConfigMap 을 읽지만 default 에서는 읽지 못해야 합니다.

스코프를 정하는 것은 역할의 종류가 아니라 바인딩의 종류입니다. 같은 역할이 어느 네임스페이스에서만 유효해지는지 확인하세요.

서브리소스만 여는 역할 만들기

rbac-lab 에 Role log-reader 를 만드세요. resources 에는 pods/log 만 넣고 pods넣지 마세요. 이 역할을 log-bot 에게 RoleBinding 으로 거세요. 결과적으로 log-botpods/log 를 읽을 수 있고, pods 자체는 읽지 못하며, pods/exec 도 쓰지 못해야 합니다.

로그는 파드와 다른 리소스 이름을 갖습니다. 상위 리소스까지 함께 열면 이 단계의 의미가 사라집니다.

권한 감사 보고서 만들기

/root/ops/rbac/out/rbac-audit.json 을 만드세요. 필드는 네 개입니다. cluster_admin_bindingsroleRef.namecluster-admin 인 ClusterRoleBinding 이름 배열이며 실제 클러스터의 개수와 정확히 일치해야 하고 기본 바인딩인 cluster-admin 이 포함돼야 합니다. wildcard_roles* 를 쓰는 역할 이름 배열(1개 이상), secret_readerssecrets 를 다루는 역할 이름 배열(1개 이상), least_privilege_violations 는 최소 권한 위반으로 판단한 항목 배열입니다.

손으로 세지 말고 클러스터에서 뽑으세요. cluster-admin 바인딩 수는 실제 값과 정확히 일치해야 합니다.