LabHub

컨테이너 보안 · 최소 권한 · 실습

최소 권한으로 컨테이너 조이기

LabHub 에서 이어서 보기

이 실습은 진짜 VM 에서 돕니다

이 상자는 파드가 아니라 KubeVirt 가 띄운 가상머신입니다. 리눅스 커널이
따로 돌고 systemd 가 실제로 서비스를 관리하며, docker 는 흉내가 아니라
진짜 도커 엔진입니다. docker run 으로 띄운 컨테이너는 실제로 프로세스가
되고 docker execdocker logs 도 그대로 동작합니다.

예전에는 이 실습이 파드 안에서 돌았습니다. 커널 권한을 전부 내려놓은 상자라
컨테이너를 띄우는 단계가 막혀 있었고, 그래서 이미지 아카이브를 직접 풀어
보는 우회로 배웠습니다. 이제 우회가 필요 없습니다.

알아 둘 것이 둘 있습니다.

목표

컨테이너를 비특권 사용자로 실행하는 두 가지 방법(런타임 플래그와 이미지 내장)을
모두 만들어 보고, 읽기 전용 루트 파일시스템·capability 전면 제거·권한 상승 차단을
하나씩 적용합니다. 마지막에는 이 조건을 만족하는 이미지를 직접 완성합니다.

왜 중요한가

"컨테이너는 격리돼 있으니 안에서 root 여도 된다"는 말이 틀린 이유는 단순합니다.
유저 네임스페이스를 쓰지 않으면 컨테이너의 UID 0 은 호스트의 UID 0 과 같은 값이고,
볼륨으로 뚫린 경로에는 그 권한이 그대로 적용됩니다. 그래서 최소 권한은 선택이
아니라 기본값이어야 합니다. 특히 USER숫자로 쓰는 습관이 중요합니다.
쿠버네티스의 runAsNonRoot 는 이름으로 된 사용자를 root 가 아니라고 판별하지
못해 파드를 거부하고, 그 오류 메시지를 처음 보면 원인을 찾는 데 한참 걸립니다.
capability 도 마찬가지입니다. 필요한 것만 빼는 방식은 언젠가 빠뜨리지만, 전부
떨어뜨린 뒤 필요한 하나만 더하는 방식은 빠뜨릴 수가 없습니다.

단계

1. /root/sec1 디렉터리를 만들고, alpine:3.20 을 아무 사용자 지정 없이 실행했을 때의 숫자 UID 만 /root/sec1/default-uid.txt 에 저장합니다. 파일에는 0 하나만 있어야 합니다.
컨테이너를 띄우지 않고도 확답할 수 있습니다. 실행 사용자는 이미지 config 의 config.User 필드에 적혀 있고, 비어 있으면 런타임이 uid 0 을 씁니다 — skopeo inspect --config oci-archive:/opt/images/alpine_3.20.tar | jq -r '.config.User' 로 확인하세요.
2. alpine:3.20 으로 sec-u 컨테이너를 --user 1000:1000 으로 백그라운드 실행하고 채점 시점까지 떠 있게 유지합니다.
3. /root/sec1/Dockerfile 을 작성해 labhub/sec:v1 이미지를 빌드합니다. USER 지시어로 숫자 UID 10001 을 지정해서 docker run --rm labhub/sec:v1 id -u10001 을 내야 합니다.
4. 비특권 사용자로 /etc 아래 파일을 만들려고 시도하고, 나온 Permission denied 오류를 표준 오류까지 포함해 /root/sec1/denied.txt 에 저장합니다.
5. sec-ro 컨테이너를 --read-only 로 백그라운드 실행하고, 그 안에서 파일 쓰기를 시도해 나온 Read-only file system 오류를 /root/sec1/ro.txt 에 저장합니다.
6. sec-caps 컨테이너를 --cap-drop=ALL --cap-add=NET_BIND_SERVICE 로 백그라운드 실행합니다.
7. sec-nnp 컨테이너를 --security-opt no-new-privileges:true 로 백그라운드 실행합니다.
8. /root/sec1/hardened.Dockerfile 을 작성해 labhub/sec:v2 이미지를 빌드합니다. 다음 네 가지를 모두 만족해야 합니다.

참고

단계 8개

  1. 기본 이미지는 root 로 뜬다
  2. 런타임 플래그로 UID 바꾸기
  3. 이미지 자체를 비root 로
  4. 권한이 없으면 무슨 일이 일어나는가
  5. 읽기 전용 루트 파일시스템
  6. capability 전부 떨어뜨리고 하나만 더하기
  7. 권한 상승 경로 막기
  8. 강화된 이미지 완성하기