보안 컨텍스트 내용과 실습 참고 책 ⇒ 쿠버네티스 완벽 가이드 👍🏻
컨테이너 보안 컨텍스트 SecurityContext - 링크 ← 파드가 아님음 주의!
각 컨테이너에 대한 보안 설정 → 침해사고 발생 시 침해사고를 당한 권한을 최대한 축소하여 그 사고에 대한 확대를 방치
종류개요
privileged | 특수 권한을 가진 컨테이너로 실행 |
capabilities | Capabilities 의 추가와 삭제 |
allowPrivilegeEscalation | 컨테이너 실행 시 상위 프로세스보다 많은 권한을 부여할지 여부 |
readOnlyRootFilesystem | root 파일 시스템을 읽기 전용으로 할지 여부 |
runAsUser | 실행 사용자 |
runAsGroup | 실행 그룹 |
runAsNonRoot | root 에서 실행을 거부 |
seLinuxOptions | SELinux 옵션 |
컨테이너 보안 컨텍스트 확인 : kube-system 파드 내 컨테이너 대상
kubectl get pod -n kube-system -o jsonpath={.items[*].spec.containers[*].securityContext} | jq
readOnlyRootFilesystem : root 파일 시스템을 읽기 전용으로 사용
#
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: rootfile-readonly
spec:
containers:
- name: netshoot
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
securityContext:
readOnlyRootFilesystem: true
terminationGracePeriodSeconds: 0
EOF
# 파일 생성 시도
kubectl exec -it rootfile-readonly -- touch /tmp/text.txt
# 기존 파일 수정 시도 : 아래 /etc/hosts파일 말고 다른 파일로 예제 만들어 두자
## 기본적으로 mount 옵션이 ro 이긴 한데. 특정 파일이나 폴더가 rw로 mount가 되어서 그곳에서는 파일 생성, 삭제등이 가능하네요.
## 특히 /etc/hosts 파일은 HostAliases로 항목 추가가 가능한데, 해당 파링은 kubelet에 의해 관리되고, 파드 생성/재시작 중 덮었여질 수 있다.
## /dev 라던가 /sys/fs/cgroup 폴더 안에서도 가능하네요.
## /etc/hostname 같은 경우는 호스트와 별도의 파일이지만 mount가 / (ro)에 속하게 되어 제한이 걸리네요.
kubectl exec -it rootfile-readonly -- cat /etc/hosts
kubectl exec -it rootfile-readonly -- sh -c "echo write > /etc/hosts"
kubectl exec -it rootfile-readonly -- cat /etc/hosts
# 특정 파티션, 파일의 ro/rw 확인
kubectl exec -it rootfile-readonly -- mount | grep hosts
kubectl exec -it rootfile-readonly -- mount | grep ro
## /proc, /dev, /sys/fs/cgroup, /etc/hosts, /proc/kcore, /proc/keys, /proc/timer_list
kubectl exec -it rootfile-readonly -- mount | grep rw
# 파드 상세 정보 확인
kubectl get pod rootfile-readonly -o jsonpath={.spec.containers[0].securityContext} | jq
Linux Capabilities : 슈퍼 유저의 힘을 작은 조각으로 나눔, Capabilities are a per-thread attribute - 링크 man-pages
# Linux Capabilities 확인 : 현재 38개
capsh --print
# proc 에서 확인 : bit 별 Capabilities - [링크](<https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h>)
cat /proc/1/status | egrep 'CapPrm|CapEff'
# 노드 Linux Capabilities 확인 : 아래 굵은색은 파드 기본 Linux Capabilities(14개)
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=us-east-1a -o jsonpath={.items[0].status.addresses[0].address})
ssh ec2-user@$N1 sudo yum -y install libcap-ng-utils
ssh ec2-user@$N1 sudo capsh --print
cap_chown 파일이나 디렉토리의 소유자를 변경할 수 있는 권한
cap_dac_override 파일이나 디렉토리의 접근 권한을 무시하고 파일이나 디렉토리에 대한 접근을 수행할 수 있는 권한 (DAC의 약자는 Discretionary access control이다)
cap_dac_read_search 파일이나 디렉토리를 읽거나 검색할 수 있는 권한
cap_fowner 파일이나 디렉토리의 소유자를 변경할 수 있는 권한
cap_fsetid 일이나 디렉토리의 Set-User-ID (SUID) 또는 Set-Group-ID (SGID) 비트를 설정할 수 있는 권한
cap_kill 다른 프로세스를 종료할 수 있는 권한
cap_setgid 프로세스가 그룹 ID를 변경할 수 있는 권한
cap_setuid 프로세스가 사용자 ID를 변경할 수 있는 권한
cap_setpcap 프로세스가 자신의 프로세스 권한을 변경할 수 있는 권한
cap_linux_immutable 파일의 immutability(불변성) 속성을 변경할 수 있는 권한을 제공
cap_net_bind_service 프로그램이 특정 포트에 바인딩(bind)하여 소켓을 개방할 수 있는 권한
cap_net_broadcast 프로세스가 네트워크 브로드캐스트 메시지를 보낼 수 있는 권한
cap_net_admin 네트워크 인터페이스나 소켓 설정을 변경할 수 있는 권한
cap_net_raw 네트워크 패킷을 송수신하거나 조작할 수 있는 권한
cap_ipc_lock 메모리 영역을 잠금(lock)하고 언락(unlock)할 수 있는 권한
cap_ipc_owner IPC 리소스(Inter-Process Communication Resources)를 소유하고, 권한을 변경할 수 있는 권한
cap_sys_module 커널 모듈을 로드하거나 언로드할 수 있는 권한
cap_sys_rawio 입출력(I/O) 포트와 같은 하드웨어 리소스를 직접 접근할 수 있는 권한
cap_sys_chroot 프로세스가 chroot() 시스템 콜을 호출하여 프로세스의 루트 디렉토리를 변경할 수 있는 권한
cap_sys_ptrace 다른 프로세스를 추적(trace)하거나 디버깅할 수 있는 권한
cap_sys_pacct 프로세스 회계(process accounting)를 위한 파일에 접근할 수 있는 권한
cap_sys_admin 시스템 관리자 권한을 제공하는 권한
cap_sys_boot 시스템 부팅과 관련된 작업을 수행할 수 있는 권한
cap_sys_nice 프로세스의 우선순위를 변경할 수 있는 권한
cap_sys_resource 자원 제한(resource limit)과 관련된 작업을 수행할 수 있는 권한
cap_sys_time 시스템 시간을 변경하거나, 시간 관련 시스템 콜을 사용할 수 있는 권한
cap_sys_tty_config 터미널 설정을 변경할 수 있는 권한
cap_mknod mknod() 시스템 콜을 사용하여 파일 시스템에 특수 파일을 생성할 수 있는 권한
cap_lease 파일의 잠금과 관련된 작업을 수행할 수 있는 권한
cap_audit_write 시스템 감사(audit) 로그에 대한 쓰기 권한
cap_audit_control 시스템 감사(audit) 설정과 관련된 작업을 수행할 수 있는 권한
cap_setfcap 파일 시스템 캡러빌리티(file system capability)을 설정할 수 있는 권한
cap_mac_override SELinux 또는 AppArmor과 같은 MAC(Mandatory Access Control) 시스템을 우회하고 자신의 프로세스가 접근 가능한 파일, 디바이스, 네트워크 등을 제한 없이 접근할 수 있는 권한
cap_mac_admin SELinux 또는 AppArmor과 같은 MAC(Mandatory Access Control) 시스템을 관리하고 수정할 수 있는 권한
cap_syslog 시스템 로그를 읽거나, 쓸 수 있는 권한
cap_wake_alarm 시스템의 RTC(Real-Time Clock)를 사용하여 장치를 깨우거나 슬립 모드를 해제할 수 있는 권한
cap_block_suspend 시스템의 전원 관리 기능 중 하나인 Suspend(절전 모드)를 방지하는 권한
cap_audit_read 시스템 감사(audit) 로그를 읽을 수 있는 권한
파드의 Linux Capabilities 기본 확인
# 샘플 파드 생성
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: sample-capabilities
spec:
containers:
- name: nginx-container
image: masayaaoyama/nginx:capsh
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
# 파드의 Linux Capabilities 기본 확인
kubectl exec -it sample-capabilities -- capsh --print | grep Current
# proc 에서 확인 : bit 별 Capabilities - [링크](<https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h>)
kubectl exec -it sample-capabilities -- cat /proc/1/status | egrep 'CapPrm|CapEff'
# 파드에서 시간 변경 시도
kubectl exec -it sample-capabilities -- date
kubectl exec -it sample-capabilities -- date -s "12:00:00"
kubectl exec -it sample-capabilities -- date
# 파드가 배포된 워커노드 IP 확인
kubectl get node -o wide | grep ip-192-168-1-170.ec2.internal
~~# 노드1로 접근
ssh ec2-user@$N1
# 노드1에 systemd-timesyncd 종료
root@i-038c6921803a6372b:~# systemctl stop systemd-timesyncd~~
# 파드에서 시간 변경 확인 >> 파드 변경 확인 후 노드의 date와 비교해보자
kubectl exec -it sample-capabilities2 -- date -s "12:00:00"
kubectl exec -it sample-capabilities2 -- date
kubectl delete pod --all
aws iam list-access-keys --user-name testuser --query 'AccessKeyMetadata[].AccessKeyId' --output text | xargs -I {} aws iam delete-access-key --access-key-id {} --user-name testuser &&
aws iam list-attached-user-policies --user-name testuser --query 'AttachedPolicies[].PolicyArn' --output text | xargs -I {} aws iam detach-user-policy --user-name testuser --policy-arn {} &&
aws iam delete-user --user-name testuser
eksctl delete cluster --name $CLUSTER_NAME && aws cloudformation delete-stack --stack-name $CLUSTER_NAME