LabHub

KCSA — 쿠버네티스 보안 어소시에이트 · 클러스터 컴포넌트 보안 · 실습

컨트롤 플레인 하드닝 점검

LabHub 에서 이어서 보기

목표

컨트롤 플레인 컴포넌트의 위험 설정을 목록으로 정리하고, etcd 저장 시 암호화 설정을 직접 작성하고,
네임스페이스 격리와 익명 접근 범위를 kubectl auth can-i측정해서 확인한 뒤,
그 근거를 묶은 하드닝 리포트를 씁니다.

왜 중요한가

보안 점검이 신뢰를 얻는 순간은 "이렇게 하는 게 좋다"가 아니라 "지금 이 클러스터는 이렇다"
를 보여줄 때입니다. kubectl auth can-i --as= 는 그 증거를 만드는 도구입니다.
RBAC 매니페스트를 읽고 머리로 계산하는 대신 apiserver 에게 직접 물어보면,
바인딩이 겹치거나 그룹 상속이 있는 복잡한 경우에도 정확한 답이 나옵니다.

EncryptionConfiguration 을 직접 써 보는 이유는 providers 배열의 순서가 전부이기 때문입니다.
identity 를 앞에 두면 암호화를 켰다고 믿으면서 평문으로 저장하게 됩니다.
이 실수는 오류를 내지 않고, 그래서 알아채기 어렵습니다.

이 실습 환경에서는 apiserver 프로세스의 실제 플래그를 바꿀 수 없습니다.
그래서 2·3·4 단계는 점검 산출물을 작성하는 형태입니다. 현장에서 CIS 벤치마크 대응이
정확히 이런 모양이라는 점도 함께 익혀 두세요 — 설정을 바꾸는 것보다 근거를 문서로 남기는 데
시간이 더 듭니다.

단계

1. 디렉터리 /root/kcsa-hard 와 네임스페이스 kcsa-hard 를 만듭니다.
2. /root/kcsa-hard/risky-flags.txt 에 프로덕션 apiserver 에 있어서는 안 되는 설정 다섯 줄을 정확히 이 형태로 적습니다 — --anonymous-auth=true, --authorization-mode=AlwaysAllow, --insecure-port=8080, --profiling=true, --service-account-lookup=false. 다른 줄은 넣지 않습니다.
3. /root/kcsa-hard/encryption-config.yaml 에 EncryptionConfiguration 을 씁니다 — apiVersion apiserver.config.k8s.io/v1, 대상 리소스는 secrets, providers 는 정확히 2 개aescbc(키 이름 key1, secret 은 base64 로 인코딩한 실제 값)와 identity 를 올바른 순서로 배치합니다.
4. /root/kcsa-hard/kubelet-checklist.txt 에 kubelet 하드닝 항목 네 줄을 정확히 이 형태로 적습니다 — authentication.anonymous.enabled=false, authentication.webhook.enabled=true, authorization.mode=Webhook, readOnlyPort=0. 다른 줄은 넣지 않습니다.
5. 네임스페이스 kcsa-team-akcsa-team-b 를 만들고 각각에 ServiceAccount app 을 만듭니다. kcsa-team-a 에 Role pod-reader(코어 그룹 pods 에 대한 get,list)와 RoleBinding app-pod-reader(대상은 kcsa-team-a 의 SA app)를 만듭니다. 그다음 kubectl auth can-i list pods--as=system:serviceaccount:kcsa-team-a:app 으로 두 네임스페이스에 각각 실행해 답이 갈리는지 확인합니다.
6. 익명 사용자로 세 가지를 물어보고 결과를 /root/kcsa-hard/anon.txt키=값 세 줄로 저장합니다 — get-pods=(네임스페이스 kcsa-hard 에서 파드 get), list-secrets=(전체 네임스페이스에서 secrets list), healthz=(비리소스 경로 /healthz 에 대한 get). 익명 주체는 --as 사칭으로 물어볼 수 없으므로(아래 참고), 관리자 권한으로 SubjectAccessReview 를 만들어 .status.allowed 를 읽고 true 는 yes, false 는 no 로 옮깁니다.
7. /root/kcsa-hard/hardening-report.md 를 작성합니다. 다음 다섯 줄이 섹션 제목으로 정확히 들어가야 합니다 — ## apiserver, ## etcd, ## kubelet, ## namespace, ## anonymous. 그리고 본문에 다음 다섯 근거가 언급되어야 합니다 — --anonymous-auth=false, aescbc, readOnlyPort=0, kcsa-team-b, system:anonymous.

참고

단계 7개

  1. 작업 공간과 네임스페이스 준비
  2. apiserver 위험 플래그 목록 작성
  3. EncryptionConfiguration 작성
  4. kubelet 인증/인가 점검 항목 정리
  5. 네임스페이스 격리를 can-i 로 증명
  6. 익명 사용자가 무엇을 할 수 있는지 관찰
  7. 하드닝 리포트로 묶기