개발강의정리/DevOps

[데브옵스를 위한 쿠버네티스 마스터] 클러스터 유지와 보안, 트러블슈팅 - 시큐리티 콘텍스트

nineDeveloper 2021. 1. 22.
728x90

시큐리티 콘텍스트


보안 컨텍스트

  • 서버 침해사고 발생 시 침해사고를 당한 권한을 최대한 축소하여 그 사고에 대한 확대를 방지

  • 침해사고를 당한 서비스가 모든 권한(root나 노드 커널 기능)으로 동작하는 경우 서비스를 탈취한 공격자는 그대로 컨테이너의 권한을 사용할 수 있음

  • 최소 권한 정책에 따른 취약점 감소

  • 보안 컨텍스트 설정에는 다음 사항을 포함

    • 권한 상승 가능 여부
    • 프로세스 기본 UID/GID를 활용한 파일 등의 오브젝트의 액세스 제어
    • Linux Capabilities를 활용한 커널 기능 추가
    • 오브젝트에 보안 레이블을 지정하는 SELinux (Security Enhanced Linux) 기능
    • AppArmor : 프로그램 프로필을 사용하여 개별 프로그램의 기능 제한
    • Seccomp : 프로세스의 시스템 호출을 필터링

포드에 시큐리티 콘텍스트 설정하기

  • 포드에 UID를 설정하면 모든 컨테이너에 적용됨
    • 컨테이너 UID/GID 설정하기
    • 권한상승 제한하기
$ kubectl exec -it security-context-demo /bin/bash / 
$ id
uid=1000 gid=3000 groups=2000
$ ps -eaf
PID  USER   TIME   COMMAND
1    1000   0:00   sleep 1h
10   1000   0:00   sh
16   1000   0:00   ps -eaf

https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod

security-context.yaml

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 1000  # UID
    runAsGroup: 3000 # GID
    fsGroup: 2000    # groups
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: busybox
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
    securityContext:
      allowPrivilegeEscalation: false # 부모 권한보다 더 높은 권한을 주지 못하도록 막음

컨테이너에 시큐리티 콘텍스트 설정하기

  • 컨테이너에 내부에 새로운 유저를 사용하면 그 설정이 우선됨
    • 컨테이너 UID/GID 설정하기

security-context-2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-2
spec:
  securityContext:
    runAsUser: 1000 # pod 전역설정
  containers:
  - name: sec-ctx-demo-2
    image: gcr.io/google-samples/node-hello:1.0
    securityContext:
      runAsUser: 2000 # 내부 설정이 우선이 됨
      allowPrivilegeEscalation: false

캐퍼빌리티 적용

https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container

security-context-4.yaml

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-4
spec:
  containers:
  - name: sec-ctx-4
    image: gcr.io/google-samples/node-hello:1.0
    securityContext:
      capabilities: # 리눅스 커널 권한 부여
        add: ["NET_ADMIN", "SYS_TIME"]

SELinux 권한

  • 모든 프로세스와 객체에 시큐리티콘텍스트(또는 레이블)을 달아 관리하는 형태

  • 넷필터와 더불어 리눅스의 핵심 보안 기능을 담당

  • 그러나 실무에서는 복잡도가 높아 오히려 소외...

  • SELinux에 대한 자세한 정보 사이트

  • 다음과 같은 형태로 취급

https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#assign-selinux-labels-to-a-container

...
securityContext:
  seLinuxOptions:
    level: "s0:c123,c456"

자료출처: https://www.lesstif.com/ws/selinux/selinux

요소 설명
사용자 시스템의 사용자와는 별도의 SELinux 사용자로 역할이나 레벨과 연계하여 접근 권한을 관리하는데 사용
역할(Role) 하나 혹은 그 이상의 타입과 연결되어 SELinux의 사용자의 접근을 허용할 지 결정하는데 사용
타입(Type) Type Enforcement의 속성중 하나로 프로세스의 도메인이나 파일의 타입을 지정하고 이를 기반으로 접근 통제를 수행
레벨(Label) 레벨은 MLS(Multi Level System)에 필요하며 강제 접근 통제보다 더 강력한 보안이 필요할 때 사용하는 기능으로 정부나 군대등 최고의 기밀을 취급하는 ㅂ곳이 아니라면 사용하지 않음

Pod Security Context 실습

Security Context 는 Container 내부에 있는 유저의 권한을 축소시켜서 사고의 범위를 줄이고자 하는 취지로 만들어져 있음

https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod

http-go deployment 생성 및 확인

$ kubectl create deploy http-go --image=gasbugs/http-go
deployment.apps/http-go created

$ kubectl get pod
NAME                      READY   STATUS    RESTARTS   AGE
http-go-568f649bb-qqcgl   1/1     Running   0          47s

http-go deployment 접속해보면 root 권한임을 알 수 있음
프로세스가 root 의 권한으로 동작하고 있음을 알 수 있음
보안이 굉장히 취약함

$ kubectl exec --stdin --tty http-go-568f649bb-qqcgl -- bash
root@http-go-568f649bb-qqcgl:/usr/src/app# id
uid=0(root) gid=0(root) groups=0(root)

root@http-go-568f649bb-qqcgl:/usr/src/app# ps -eaf
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 10:27 ?        00:00:00 /usr/src/app/main
root          55       0  0 12:18 pts/0    00:00:00 bash
root          64      55  0 12:20 pts/0    00:00:00 ps -eaf

security-context.yaml 설정을 수정해서 사용하기 위해 wget 다운로드 받기

$ wget https://k8s.io/examples/pods/security/security-context.yaml

Group 번호 임의로 수정

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 1234
    fsGroup: 8888
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: busybox
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
    securityContext:
      allowPrivilegeEscalation: false

kubectl 로 생성

$ kubectl create -f security-context.yaml
pod/security-context-demo created

접속해서 권한을 확인해보면 1000 으로 되어있어 root 권한의 파일들을 삭제할 수 없음

$ kubectl exec --stdin --tty security-context-demo -- sh
/ $ id
uid=1000 gid=1234 groups=8888
/ $ ps -eaf
PID   USER     TIME  COMMAND
    1 1000      0:00 sleep 1h
   15 1000      0:00 sh
   22 1000      0:00 ps -eaf

securityContext 내부 유저를 2000 으로 설정

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-2
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 1234
    fsGroup: 8888
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: busybox
    command: [ "sh", "-c", "sleep 1h" ]
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
    securityContext:
      allowPrivilegeEscalation: false
      runAsUser: 2000

kubectl 로 생성

$ kubectl create -f security-context-2.yaml
pod/security-context-demo-2 created

UID 가 2000 으로 설정된 것을 확인할 수 있음

$ kubectl exec -it security-context-demo-2 -- sh
/ $ id
uid=2000 gid=1234 groups=8888
/ $ ps -eaf
PID   USER     TIME  COMMAND
    1 2000      0:00 sleep 1h
    7 2000      0:00 sh
   14 2000      0:00 ps -eaf

Set capabilities for a Container 실습

https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container

capabilities 가 설정된 것과 그렇지 않은 컨테이너의 비교

security-context-3.yaml 파일 생성

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-3
spec:
  containers:
  - name: sec-ctx-3
    image: gcr.io/google-samples/node-hello:1.0
$ kubectl apply -f https://k8s.io/examples/pods/security/security-context-3.yaml
pod/security-context-demo-3 created

security-context-4.yaml 파일 생성

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-4
spec:
  containers:
  - name: sec-ctx-4
    image: gcr.io/google-samples/node-hello:1.0
    securityContext:
      capabilities:
        add: ["NET_ADMIN", "SYS_TIME"]
$ kubectl apply -f https://k8s.io/examples/pods/security/security-context-4.yaml
pod/security-context-demo-4 created

pod 생성 확인

$ kubectl get pod
NAME                      READY   STATUS    RESTARTS   AGE
security-context-demo-3   1/1     Running   0          11s
security-context-demo-4   1/1     Running   0          6s

security-context-demo-3 접속 후 시간변경 시도시 권한이 없어서 시간변경에 실패함

$ kubectl exec -it security-context-demo-3 -- sh
# date
Thu Jan 21 12:47:52 UTC 2021
# date +%T -s "12:00:00"
date: cannot set date: Operation not permitted
12:00:00

security-context-demo-4 접속 후 시간변경 시도시
capabilitiesSYS_TIME 권한이 있어서 시간변경에 성공하는 것을 확인할 수 있음

$ kubectl exec -it security-context-demo-4 -- sh
# date
Thu Jan 21 12:49:30 UTC 2021
# date +%T -s "12:00:00"
12:00:00
728x90

댓글

💲 추천 글