리눅스 컨테이너의 핵심만 구현한 570줄 코드
원제 Linux containers in 500 lines of code (2016)
145 포인트댓글 44
Key Point
Linux 커널이 제공하는 namespace, capability, cgroup, seccomp 등 격리 메커니즘이 실제로 어떻게 연결되고 어떤 순서로 적용되는지 간단한 코드로 명확히 보여주므로, 컨테이너 보안의 기초를 이해하고 싶은 개발자에게 필수적이다.
핵심 요약
- Linux 컨테이너를 최소 제약으로 직접 구현한 경험을 공유하는 2016년 기술 글로, 570줄의 C 코드로 신뢰할 수 없는 코드를 안전하게 실행하는 방식을 설명한다.
- 컨테이너는 namespace(프로세스 그룹화), capability(root 권한 세분화), cgroup과 setrlimit(리소스 제한), seccomp(시스템콜 필터링)이라는 여러 커널 메커니즘이 겹쳐 작동한다.
- clone() 시스템콜에 CLONE_NEWNS, CLONE_NEWPID, CLONE_NETIPC, CLONE_NEWNET, CLONE_NEWUTS 등의 플래그를 전달해 자식 프로세스를 새로운 네임스페이스에서 생성하고, 메모리와 CPU 제한, 마운트 변경, UID/GID 전환을 순차적으로 수행한다.
- CAP_DAC_READ_SEARCH, CAP_MKNOD, CAP_SYS_ADMIN, CAP_SYS_BOOT, CAP_SYS_MODULE 등 20개 이상의 capability를 프로세스 경계와 bounding set에서 제거해 컨테이너 내 권한을 제한한다.
- CAP_DAC_OVERRIDE, CAP_NET_ADMIN, CAP_SETUID, CAP_SYS_PTRACE 같은 일부 capability는 namespace가 이미 격리하거나 마운트 경계 내에서만 작동해 유지할 수 있다.
- User namespace를 지원하면 uid/gid 맵핑을 통해 컨테이너 내부의 root(uid 0)를 호스트의 unprivileged 사용자로 매핑할 수 있지만, 다수의 권한 상승 취약점이 발견되어 신중한 사용이 필요하다.
- 마운트 격리, 호스트 파일시스템 감싸기, pivot_root로 루트 변경을 수행해 컨테이너가 호스트 파일에 접근하지 못하도록 한다.
- seccomp을 통해 mount, ioctl, ptrace, reboot 등 위험한 시스템콜을 필터링하되, execve, mmap, clone 같은 필수 호출은 허용한다.
- 이 구현은 교육 목적으로 기술적 제약 메커니즘이 어떻게 상호작용하는지 보여주지만, 프로덕션 컨테이너 보안을 위해서는 모든 가능한 것을 제한해야 한다.