연재 시리즈

pkos 스터디 5주차 4편 - securityContext.capability

악분 2023. 4. 7. 00:54
반응형

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

반응형