KCSA — 쿠버네티스 보안 어소시에이트 · 진짜 클러스터에서 훔쳐 보기 · 이론
base64 는 암호화가 아니다
한 줄 요약
저장소도 인증 체인도 감사 로그도 없는 곳에서는 공격 표면이 글로만 남습니다. KCSA 는 실제로 훔쳐 봐야 배워집니다.
왜 직접 열어 봐야 하나
앞 모듈에서 위협 모델과 공격 표면을 배웠습니다. 그런데 그 실습이 도는 곳에는 저장소도 apiserver 인증 체인도 감사 로그도 없어서, 이 전부가 글로만 남아 있었습니다.
KCSA 를 배우려면 실제로 훔쳐 봐야 합니다. 그중 첫째가 이것입니다.
base64 는 인코딩이지 암호화가 아니다
kubectl get secret -o yaml 이 보여 주는 base64 는 열쇠 없이 base64 -d 한 번이면 되돌아갑니다. 아무것도 숨기지 못합니다.
진짜 문제는 아래에 있습니다. etcd(k3s 는 kine/sqlite)에는 값이 raw 로 들어갑니다. 저장소 파일을 읽는 사람은 디코딩도 필요 없이 평문을 봅니다.
노드에 root 로 들어온 공격자 파일을 그대로 읽는다etcd 백업을 손에 넣은 사람 백업 안에 평문이 그대로저장소 디스크를 복제한 사람 스냅샷에 남아 있다그래서 저장 시 암호화를 따로 켜야 합니다(기본이 꺼짐). 그런데 켜는 것에도 함정이 둘 있습니다.
- 제공자 순서를 바꾸면 아무것도 암호화되지 않는데 오류도 안 납니다
- 암호화는 소급되지 않아 옛 시크릿을 다시 써야 바뀝니다
can-i 가 no 여도 안전하지 않다
시크릿 읽기 권한이 없어도 파드를 만들 수 있으면 그 파드에 시크릿을 마운트해 읽어 냅니다. create pods 는 create secrets 보다 훨씬 센 동사입니다 — hostPath·privileged·다른 SA 지정까지 열려 있기 때문입니다.
실무에서 진짜 중요한 것
저장 시 암호화를 켠 뒤에는 옛 시크릿을 전부 다시 써야 합니다. 암호화는 소급되지 않습니다. 켰다는 사실만 믿고 지나가면 이미 저장된 평문은 그대로 남아, 백업과 디스크 스냅숏에도 계속 실려 나갑니다.
제공자 순서를 바꿔 놓고도 오류가 안 나므로 반드시 되읽어 확인합니다. 설정은 받아들여지고 파드도 정상인데 아무것도 암호화되지 않는 상태가 만들어집니다. 저장소를 직접 열어 값을 보는 것이 유일하게 확실한 검증입니다.
권한 감사는 동사 하나가 아니라 도달 가능한 경로로 봅니다. can-i get secrets 가 no 여도 create pods 가 yes 면 그 파드에 시크릿을 마운트해 읽어 냅니다. create pods 는 hostPath·privileged·다른 SA 지정까지 열려 있어서, 사실상 노드 권한에 가깝습니다.
다음 실습에서 이것들을 진짜 클러스터에서 직접 훔쳐 가며 확인합니다.