Security Context
Mont Kim / February 2023 (596 Words, 4 Minutes)
중간과제 Security Context
매주 열심히 정리해서 중간과제는 면제를 받았지만 그래도 천천히 아는것을 정리해보고자 PKOS 스터디 중간과제로 Security Context에 대해 다뤄봅니다. SecurityConetext 이전에 컨테이너 기술부터 앞서 볼 필요가있습니다.
LXC
컨테이너 기술은 LXC라는 Linux Container 라는 단어의 약자로
리눅스의 커널을 공유하며 논리적인 분리 (프로세스등의) 를 실행하는데서 시작되었다.
LXC(LinuX Containers)는 호스트에서 여러개의 리눅스 시스템(컨테이너)를 실행하기 위한 운영 시스템 레벨 가상화 방법 이다
리눅스 커널은 cgroups를 통해 가상화 머신을 시작하지않고 자원 ( CPU, 메모리, 블록 I/O, 네트워크)를 사용한다.
LXC는 groups와 namespace를 결합하여 어플리케이션을 위한 독립된 환경을 제공합니다.
Docker에서도 LXC를 사용 할 수 있으며, 이를 통해 이미지 관리와 개발 서비스를 제공합니다
LXC (컨테이너)의 주요 기술
컨테이너 기술은 리눅스 커널에서 제공하는 기능을 이용해 탄생했습니다.
리눅스 컨테이너 공식문서에서의 기능은 다음과 같습니다
· namespace
- 커널 자원들을 구분해서 이를 프로세스에 제공해 그 프로세서의 소속된 자원처럼 가상화합니다.
- 프로세스 테이블(PIDs), ipc, 네트워크(IP주소, 방화벽 등), User ID, 마운트 포인트 등을 가상화할 수 있습니다.
· Apparmor와 SELinux 프로파일
· Seccomp 정책
· Chroots
- 프로세스의 루트 디렉토리를 변경해 다른 프로세스가 액세스 할 수있는 디렉토리를 제한할 수 있습니다.
· kernel capability
· CGroups
- 프로세스의 리소스를 격리하고 사용을 제어하는 기능입니다.
- 자원 제한
- 특정 프로세스의 메모리 사용량을 제한.
- 우선 순위
- 특정 프로세스에 더 많은 CPU와 디스크 I/O 처리량을 할당.
- 기록
- 프로세스가 자원을 얼마나 사용하고 있는지 측정.
- 제어
- 프로세스를 멈추거나, 프로세스의 체크포인트를 설정해주거나 재시작 가능.
- 자원 제한
Linux Containers - LXC - Introduction
해당 링크에서 자세한 내용을 확인 하실 수 있습니다.
커널을 공유하기때문에 컨테이너는 호스트OS의 커널에 치명적인 영향을 미칠수없게 보안을 적용
종류 | 개요 |
---|---|
privileged | 특수 권한을 가진 컨테이너로 실행 |
capabilities | Capabilities의 추가와 삭제 |
allowPrivilegedEscalation | 컨테이너 실행시 상위 프로세스보다 많은 권한을 부여할지 여부 |
readOnlyRootFilesystem | root 파일 시스템을 읽기 전용으로 할지 여부 |
runAsUser | 실행 사용자 |
runAsGroup | 실행 그룹 |
runAsNonRoot | root에서 실행을 거부 |
seLinuxOptions | SELinux 옵션 |
격리된 컨테이너공간에서 호스트의 디렉토리에 접근하거나, 프로세스에 간섭하는것이 막혀있는데
이를 가능하게 해주는 기능의 대표적인 예로 privilege 모드가 있다.
컨테이너를 privilege 모드로 실행하면, HOST OS의 커널수준에서 모든 동작을 컨트롤 할 수 있는데
컨테이너에서 HOST에 모든 권한을 부여했기때문에, 신뢰성에 문제가 발생 할 수 있다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: ngin
image: nginx:latest
securityContext:
privileged: true
Capabilities
Privilege모드의 권한을 제한적으로 부여하는 방법으로는 Capabilities라는것이 존재한다.
컨테이너 환경과는 별개로 리눅스환경에서 계정단위로도 Capabilites 권한을 개별적으로 부여 할 수 있지만, 컨테이너 단위로도 이 권한이 부여가 가능합니다
capabilities(7) - Linux manual page
쿠버네티스또한 컨테이너 기반의 환경을 제공하기때문에
똑같이 Capabilities를 부여할 수 있는 방법이 존재합니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: ngin
image: nginx:latest
securityContext:
capabilities:
add: ["SYS_ADMINH"]
security context를 제일 처음 공부하게되었을때, 찾아보고있던 권한중
쿠버네티스 관리자가 자원을 생성할 때 mount
하는것과는 별개로, pod 내부에서 마운트 권한을 획득 할 수 있는 방법에 대해 찾아보다 찾게된 예시입니다.
하지만 이름에서도 느낄수 있다시피
Capabilities의 man page 공식문서를 읽어도 CAP_SYS_ADMIN에 부여되는권한들이 참 다양하기때문에
mount(2) 기능을 위해서만 이 권한을 부여하는게 못마땅하다면
위에 설명헀던 LXC의 주요기능중 하나인 AppArmor 등의 프로파일로 수행을 허용 또는 차단하는 구체적인 프로파일을 작성 할 수 있습니다.
하지만 Apparmor는 Security Context에서 다루는 범위가 아니기때문에, 이번 문서에서는 키워드만 전달드리고 넘어가겠습니다.
또 다른 한가지 예시를 들어보겠습니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: ngin
image: nginx:latest
securityContext:
capabilities:
add: ["SYS_RESOURCE"]
상용 서버들에서 Ulimit 값을 이용하여 프로세스의 자원한도를 설정해
Soft limit과 hard limit을 사용하곤 합니다.
이때 컨테이너 내부에서도 기본설정값 외에 추가적으로 설정하기위해선 POD자체적으로 SYS_RESOURCE 라는 권한이 있어야 ulimit값을 수정 할 수 있습니다.
프로세스 사용자 ID와 그룹 ID 지정
쿠버네티스에서는 pod나 컨테이너에서 구동되는 프로세스의 사용자 ID 와 그룹 ID를 지정 할 수 있습니다.
생성되는 pod의 모든 프로세스기 root권한으로 실행되는것을 방지하기위해 사용자 application 프로세스의 사용자 ID, 그룹 ID를 지정해 특정 자원의 접근을 허용할 수 있습니다.
runasUser
컨테이너가 실행하는 Entrypoint (실행 사용자)를 변경 할 수 있습니다
보안을 위해서라도 기본적으로 root 사용자 이외의 사용자로 실행하는것이 좋습니다
apiVersion : v1
kind: Pod
metadata:
name: sample-runuser
spec:
securityContext:
runAsUser: 65534
runAsGroup: 65534
containers:
- name: tools-contatiner
image: amsy810/tools:v2.0
기동한 컨테이너의 명령어 실행 사용자를 확인해보면
nobody(UID: 65534) 그룹으로 실행되는것을 확인 할 수있습니다
root 사용자로 실행 제한 (runAsNonRoot)
실행 사용자를 변경하지 않고 단순히 root 사용자로 실행을 거부하도록 체크할수도 있다
apiVersion : v1
kind: Pod
metadata:
name: sample-nonroot
spec:
securityContext:
runAsNonRoot: true
containers:
- name: tools-contatiner
image: amsy810/tools:v2.0
위와같이 실행하면 pod가 root로 실행되는것을 방지 할 수 있다
securityContext에서 다루지않은 LXC만의 기능들로도 수많은 기능들을 제한 할 수 있습니다.
제가 관리하는 쿠버네티스 시스템에서는 우분투만 다루기때문에
centos와는 다르게 selinux가 default로 설치되어있지 않지만
그외에도 Apparmor나 Cgroup등에 대한 내용도 천천히 다뤄봐야겠습니다
그럼 20000