TT Lab
블로그 시작하기
배우기 러닝패스 코스

지운 토큰이 기록에서 문을 연다

Secret 은 이름만 비밀이었다

TT Lab 에서 이어서 보기

한 줄 요약

쿠버네티스 Secret 은 기본으로는 base64 로 적힌 평문이고, 클러스터 저장소에도 평문으로 들어갑니다. 저장 암호화는 디스크와 백업을, RBAC 은 API 를 지킵니다. 둘 중 하나만으로는 막히지 않습니다.

왜 이게 문제인가

Secret 이라는 이름 때문에 많은 사람이 "알아서 암호화된다" 고 생각합니다. 실제로는 매니페스트의 값이 base64 로 인코딩됐을 뿐이고, API 서버는 그것을 그대로 etcd(k3s 라면 sqlite 위의 kine)에 저장합니다. 저장소 백업 파일 하나, 컨트롤 플레인 노드의 디스크 하나가 새면 클러스터의 모든 비밀번호가 함께 나갑니다.

권한 쪽도 비슷합니다. 모니터링·보고·백업 도구는 "모든 것을 읽을 수 있어야 편하다" 는 이유로 클러스터 전체 읽기 권한을 받는 일이 많습니다. 그 권한에 secrets 가 들어 있으면, 그 도구의 토큰 하나가 모든 네임스페이스의 비밀번호를 여는 열쇠가 됩니다.

어떻게 동작하나

저장 암호화는 API 서버의 EncryptionConfiguration 이 맡습니다. 어떤 자원(보통 secrets)을 어떤 방식(aescbc·aesgcm·secretbox·KMS)으로 암호화할지 적어 두면, API 서버가 저장하기 직전에 암호화하고 읽을 때 풉니다. 저장된 값은 k8s:enc:aescbc:v1:<키 이름>: 같은 머리말로 시작합니다. k3s 는 이 설정을 k3s secrets-encrypt 하위 명령으로 관리합니다.

중요한 점이 둘 있습니다. 첫째, 암호화는 켠 뒤에 새로 쓰는 객체에만 적용됩니다. 이미 저장된 Secret 은 다시 써야 암호문이 됩니다. 둘째, 저장소는 옛 리비전을 압축 전까지 들고 있습니다. 암호화를 켠 뒤에도 옛 평문 행은 한동안 남으므로, 이미 노출됐다고 볼 수 있는 값은 회전해야 합니다.

RBAC 은 API 를 지킵니다. 클러스터 전체에 걸리는 ClusterRoleBinding 대신 네임스페이스 안의 Role·RoleBinding 으로, 필요한 자원과 동사만 줍니다. kubectl auth can-i <동사> <자원> --as <신원> 으로 그 신원이 실제로 무엇을 할 수 있는지 확인할 수 있습니다. 마지막으로 감사 정책으로 Secret 접근을 남기되, 수준은 Metadata 로 둡니다. Request 나 RequestResponse 로 남기면 감사 로그가 비밀값 본문을 적어 새 유출원이 됩니다.

현장에서 만나는 모습

"보고용 계정에 클러스터 읽기 권한을 줬더니 secrets 까지 따라왔다" 는 사고는 내장 ClusterRole 을 그대로 묶을 때 자주 납니다. 권한 검토 때는 바인딩 목록만이 아니라 can-i --list 로 결과를 보는 편이 확실합니다.

저장 암호화를 켠 뒤에 "다시 쓰기" 를 빼먹는 일도 흔합니다. 상태 화면에는 Enabled 가 찍히니 끝난 것처럼 보이지만, 오래된 Secret 일수록 평문 그대로 남아 있습니다. 켰다는 것과 적용됐다는 것은 저장소를 직접 열어 봐야 구별됩니다.

고친 뒤 무엇으로 확인하나

쿠버네티스 쪽 확인은 "설정에 적혀 있다" 와 "실제로 그렇게 동작한다" 를 나눠서 합니다.

English corner

다음 실습에서 할 것

k3s 한 대에서 Secret 을 디코딩하고, 저장소 행에서 평문을 찾고, 보고용 계정이 비밀번호를 읽는 것을 봅니다. 권한을 줄이고, 저장 암호화를 켜 기존 Secret 까지 다시 쓰고, 값을 회전한 뒤, 거절된 접근이 감사 로그에 값 없이 남는지 확인합니다.

한 걸음 더 — 백업도 함께 본다

저장소를 암호화해도 백업이 평문이면 구멍이 그대로 남습니다. etcd 스냅숏이나 k3s 의 데이터 디렉터리를 백업할 때 그 백업이 어디에 어떤 권한으로 저장되는지, 암호화돼 있는지 함께 봐야 합니다. 또 하나는 로그입니다 — 애플리케이션이 Secret 값을 디버그 로그에 찍거나, 환경 변수로 받은 비밀번호가 크래시 덤프에 남는 경로가 흔합니다. Secret 저장소와 RBAC 을 조인 다음에는 '그 값이 또 어디로 복제되는가'(백업·로그·모니터링 레이블)를 한 바퀴 따라가 보는 것이 마무리입니다.