Docker 컨테이너가 의도대로 동작하지 않을 때 가장 손쉬운 해결책이 무엇일까요? 많은 개발자가 --privileged 플래그를 붙여 실행합니다. 동작은 하지만, 이는 컨테이너 격리의 의미를 사실상 포기하는 매우 위험한 설정입니다. 이번 글에서는 Privileged 모드가 실제로 무엇을 여는지, 어떤 공격이 가능한지, 그리고 대안은 무엇인지 정리합니다.
Privileged 모드란 무엇인가
docker run --privileged로 실행한 컨테이너는 호스트의 거의 모든 리소스에 접근할 수 있는 권한을 갖습니다. 구체적으로 다음이 허용됩니다.
- 모든 Linux Capabilities 활성화
- 호스트의 모든 디바이스에 접근
- AppArmor, SELinux 등의 보안 프로파일 비활성화
- cgroups 설정 우회 가능
- 호스트 파일시스템 마운트 가능
한마디로 요약하면 “컨테이너 안에서 호스트 루트 권한과 동일한 일을 할 수 있다”는 의미입니다.
왜 위험한가: 실전 공격 시나리오
시나리오 1: 호스트 파일시스템 탈취
Privileged 컨테이너는 호스트의 디스크를 마운트하고 내용을 읽거나 수정할 수 있습니다. 예를 들어 /etc/shadow 파일에 접근하거나, /root/.ssh/authorized_keys에 공격자의 공개키를 주입하는 것이 가능합니다.
시나리오 2: 호스트 커널 모듈 로드
Privileged 모드에서는 modprobe로 커널 모듈을 로드할 수 있습니다. 악성 커널 모듈이 로드되면 루트킷 설치까지 가능해져 호스트가 완전히 장악됩니다.
시나리오 3: 컨테이너 이스케이프
Privileged 컨테이너에서 호스트의 cgroup을 조작해 컨테이너를 탈출하는 공격이 알려져 있습니다. 여러 CVE가 발표되었고, 실제 공격 코드도 공개되어 있습니다.
언제 Privileged가 필요하다고 오해되는가
많은 경우 Privileged가 없어도 되는데 습관적으로 붙이는 경우가 많습니다. 대표적인 오해 사례:
- “Docker-in-Docker가 필요해서” → 대안 존재 (아래 설명)
- “systemd가 필요해서” → 특정 capabilities만 부여로 해결
- “USB 디바이스 접근 때문에” →
--device옵션으로 해당 디바이스만 노출 - “네트워크 설정이 안 돼서” →
NET_ADMINcapability만 추가
안전한 대안
대안 1: 최소 권한 원칙 — Capabilities 선택적 부여
Privileged 대신 필요한 Capability만 지정해 부여합니다.
- 네트워크 관리:
--cap-add=NET_ADMIN - 시간 설정:
--cap-add=SYS_TIME - 프로세스 추적:
--cap-add=SYS_PTRACE
보안팀에 제출할 때도 “Privileged 없음, NET_ADMIN만 사용”이라고 명시할 수 있어 감사 대응에도 유리합니다.
대안 2: Device 직접 지정
특정 디바이스에만 접근이 필요하면 --device로 정확히 지정합니다.
예시:
- USB 디바이스:
--device=/dev/ttyUSB0 - GPU:
--gpus all또는 nvidia-docker
대안 3: Docker-in-Docker 대신 Docker 소켓 공유
CI/CD 파이프라인에서 컨테이너 내부에서 Docker 명령을 실행해야 하는 경우, Privileged 모드를 쓰는 대신 호스트의 Docker 소켓을 마운트하는 방법이 있습니다.
-v /var/run/docker.sock:/var/run/docker.sock
단, 이 방법도 보안 위험이 있으므로 신뢰할 수 있는 이미지만 사용해야 합니다. 완전히 격리된 Docker-in-Docker가 필요하다면 Kaniko, Buildah, Podman 같은 Rootless 빌드 도구를 검토하세요.
대안 4: Rootless Container 전환
Docker Rootless 모드는 사용자 네임스페이스를 활용해 루트 권한 없이 컨테이너를 실행합니다. 2020년 이후 Docker CE에서 공식 지원되며, 보안 중요 환경에서 적극 검토할 가치가 있습니다.
Kubernetes 환경에서의 통제
Kubernetes에서는 PodSecurity Admission 또는 OPA Gatekeeper로 Privileged 컨테이너 배포를 원천 차단할 수 있습니다.
Pod Security Standards
- Restricted: Privileged 금지, 대부분의 Capability 금지
- Baseline: Privileged 금지, 일부 Capability 허용
- Privileged: 모든 제한 해제 (시스템 워크로드용)
일반 워크로드는 Restricted, 시스템 에이전트(Datadog, Falco 등)는 Baseline으로 구성하는 것이 모범 사례입니다.
실전 체크리스트: 안전한 컨테이너 실행
--privileged금지 (감사 로그에서 검색)USER지시어로 non-root 사용자 지정- Read-only 루트 파일시스템 (
--read-only) - 필요한 Capability만
--cap-add로 명시 - 불필요한 Capability 제거 (
--cap-drop=ALL후 개별 추가) - Seccomp 프로파일 적용
- AppArmor 또는 SELinux 활성화
- 이미지 취약점 스캔 (Trivy, Snyk)
감사 및 모니터링
보안 규정이 엄격한 환경에서는 컨테이너 런타임 행위를 지속적으로 감시해야 합니다. 다음 도구들이 유용합니다.
- Falco: 컨테이너 런타임 보안 모니터링
- Sysdig Secure: 상용 컨테이너 보안 플랫폼
- Azure Defender for Containers: Azure 통합 솔루션
Falco 규칙 예시로 “privileged 컨테이너 실행 감지” 규칙이 기본 제공되며, 이를 SIEM과 연동해 즉시 알림을 받을 수 있습니다.
마무리
Privileged 모드는 “동작은 하지만 절대 운영에 올리면 안 되는” 설정입니다. 개발·테스트 편의상 임시로 쓰는 것까지는 이해되지만, CI/CD나 운영 배포에는 절대 포함되지 않아야 합니다. 정책 수준에서 차단하고 대안을 팀에 교육하는 것이 보안 사고를 예방하는 가장 확실한 방법입니다.