5주차 네번째 주제는 pod securityContext.capability입니다.
Linux capability
리눅스는 capability라는 기능으로 커널권한을 분리합니다. 리눅스 초창기에는 root계정이 모든 권한이 있었고 커널 2.2부터 capability로 커널권한을 분리했습니다. 그래서 root계정이라도 capability설정이 없다면 작업이 제한됩니다. capability에 대한 자세한 내용은 man명령어로 볼 수 있습니다.
man capabilities
capability는 계정과 프로세스에 설정됩니다. 계정은 capsh명령어로 확인할 수 있습니다.
capsh --print
프로세스 capability는 프로세스 정보에서 비트마스크로 표현됩니다.
cat /proc/1/status | egrep 'CapPrm|CapEff'
실행파일이 프로세스로 변하므로 실행파일에서도 capability를 조회할 수 있습니다. 예를 들어 ping실행파일은 네트워크 통신을 위한 capability를 가지고 있습니다.
getcap /bin/ping
capability목록
capability목록은 매우 많습니다. man capability에서 확인할 수 있습니다.
man capabilities
쿠버네티스에서 capability
쿠버네티스 pod에서도 linux처럼 capability를 설정하여, 컨테이너 커널권한을 설정할 수 있습니다. pod는 결국 커널 위에 동작하는 프로세스이므로 capability영향를 제어할 수 있습니다.
pod에서 capsh조회
pod안에서 capsh를 조회해보겠습니다. 아래 nginx pod를 배포합니다.
# kubectl apply -f sample-capabilities.yaml
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
그리고 nginx pod쉘에 접속합니다.
kubectl exec -it sample-capabilities -- /bin/sh
계정에 설정된 capability를 확인합니다.
capsh --print | grep Current
pid 1인 프로세스에 설정된 capability를 확인합니다.
cat /proc/1/status | egrep 'CapPrm|CapEff'
확인해보셨나요? pod에서 확인한 capablity는 리눅스에서 확인한 결과와 차이가 없습니다.
capability 제거
securitycontext를 수정하여 pod에 할당된 capability를 제거할 수 있습니다. 예제로 netshoot pod에서 NET_RAW를 제거하여 ping통신을 못하도록 설정해보겠습니다
먼저 정상 netshoot pod를 배포합니다.
# kubectl apply -f netshoot-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: netshoot-pod
spec:
replicas: 1
selector:
matchLabels:
app: netshoot-pod
template:
metadata:
labels:
app: netshoot-pod
spec:
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
netshoot pod 쉘 안에서 google서버에 ping을 날려보세요. google서버와 잘 통신이 됩니다.
kubectl exec -it netshoot-pod -- zsh
ping google.ecom
이번엔 ping통신에 필요한 NET_RAW capability를 제거합니다. securitycontext.capabilities에서 drop으로 NET_RAW를 제거했습니다.
# kubectl apply -f netshoot-pod-without-netraw.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: netshoot-pod-without-netraw
spec:
replicas: 1
selector:
matchLabels:
app: netshoot-pod
template:
metadata:
labels:
app: netshoot-pod
spec:
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
# capability제거
securityContext:
capabilities:
drop: ["NET_RAW"]
terminationGracePeriodSeconds: 0
NET_RAW가 제거된 pod에서 ping을 날려보면 권한이 없다고 거부됩니다.
kubectl exec -it netshoot-pod-without-netraw -- zsh
ping google.ecom
오픈소스 활용사례
capability를 적절하게 사용하는 것은 시스템 보안정책을 따르는데 중요합니다. pod가 공격당할 때 최대한 커널 권한을 제한할 수 있기 때문엡니다.
오픈소스 중 elasticsearch는 capability를 모두 제거하는 사례도 있습니다.
helm repo add elastic https://helm.elastic.co
helm template elasticsearch elastic/elasticsearch
'연재 시리즈' 카테고리의 다른 글
pkos 스터디 5주차 6편 - securityContext.allowPrivilegeEscalation (0) | 2023.04.08 |
---|---|
pkos 스터디 5주차 5편 - securityContext.readOnlyRootFilesystem (0) | 2023.04.08 |
pkos 스터디 5주차 3편 - securityContext.privileged (0) | 2023.04.04 |
pkos 스터디 5주차 2편 - pod에서 인스턴스 메타데이터 접근 가능하면 생기는 위험 (0) | 2023.04.03 |
pkos 스터디 5주차 1편 - AWS EC2 인스턴스 메타데이터 (0) | 2023.04.03 |