- 이 내용은 쿠버네티스 보안의 중요성을 환기하는 게 목적임
- Secret 저장 장소
- 사용자가 kubectl 명령을 통해 리소스 선언하면 쿠버네티스는 이 리소스를 정의한 메니페스트 파일 만들어 etcd에 저장
- 사용자가 Secret 리소스 선언하면 Secret도 etcd에 저장
- 사용자가 Secret을 볼륨 혹은 환경변수로 읽는 pod 만들면 Secret은 해당 pod에 저장
- Secret 저장되는 etcd와 secret이 사용되는 pod 해킹하면 Secret에 저장된 비밀번호 알 수 있음
- 사전 준비
- kubeadm으로 클러스터 생성
- 실습 위해 세가지 리소스 미리 만듦: Secret credit-card, pod app1, pod app2
- etcd 해킹
- etcd: 쿠버네티스 클러스터 상태 저장하는 키-값 데이터 저장소. 쿠버네티스에 선언된 모든 정보가 여기에 저장. Secret도 etcd 조회해보면 알 수 있음
- 1.1 etcdctl로 비밀번호 찾기
- kube-apiserver 메니페스트 조회해 etcd 서버의 certificate authority, 공개 키, 개인 키 가져옴
- etcd 편하게 조작하는 etcdctl 명령 통해 비밀번호 찾음
- 1.2 etcd DB 직접 접근해 가져오기
- etcd가 동작하는 프로세스 찾고, 해당 프로세스 데이터 모두 탐색해 비밀번호 찾음
- ps aux | grep etcd -etcd PID 가져옴
- ll /proc/<pid>/fd 보면 db라고 적힌 link 파일 보임
- cat /proc/<pid>fd/<db> | grep -A10 -B10 credit-card 명령 통해 사전에 만든 비밀번호 찾음
- pod 해킹
- kubectl exec 통해 가져오기
- 쿠버네티스 조회하는 적절한 권한 있다면 kubectl 명령 통해 비밀번호 가져올 수 있음
- 컨테이너에 직접 접근해서 가져오기
- 워커 노드에서 도커 명령 자유롭게 쓸 수 있으면 비밀번호 빼낼 수 있음
- pod app1이 스케줄된 워커 노드에서 컨테이너 찾아 컨테이너에 등록된 환경 변수 목록 추출할 수 있음
- crictl pods - app1의 Pod ID 찾음
- crictl ps - Pod ID에 상응하는 컨테이너 찾음
- crictl inspect <container id> | grep -A16 env - 해당 컨테이너를 상세 조회해 환경 변수 추출
- Secret에 접근 권한 있는 ServiceAccount로 가져오기
- Pod의 ServiceAccount가 Secret에 접근 권한 있다면 pod 내부에서 API 호출로 비밀번호 찾을 수 있음
- 위에서 설명한 해킹 막는 방법
- ‘최소 권한 원칙’ 따라 불필요한 권한 있는 service account 만들지 않기
- 소셜 엔지니어링 등 위협에 대비해 사용자 credential 노출 X
- EncryptionConfiguration 리소스 통해 etcd 암호화