3. Docker容器运行时安全:容器权限控制、Capabilities机制、Seccomp与AppArmor配置
容器运行时安全是Docker安全合规体系中最贴近生产环境的防线。默认情况下,Docker容器以受限的用户空间运行,但若未对权限、系统调用和访问控制进行精细化配置,攻击者仍可能利用容器逃逸漏洞或滥用宿主资源。本章从权限控制、Capabilities裁剪、系统调用过滤(Seccomp)和强制访问控制(AppArmor)四个维度,构建容器运行时的纵深防御体系。
3.1 容器权限控制:从特权模式到细粒度限制
Docker提供从“完全隔离”到“完全开放”的权限谱系。生产环境应避免使用--privileged标志,该标志赋予容器几乎等同于宿主root的权限,包括访问所有设备、加载内核模块等能力。
| 权限模式 | 启动参数 | 安全等级 | 典型使用场景 |
|---|---|---|---|
| 默认模式 | 无额外参数 | 高 | 无状态微服务、Web应用 |
| 添加设备 | --device /dev/sda |
中 | 需要访问特定硬件(如GPU、USB) |
| 特权模式 | --privileged |
低 | 仅限调试、系统级工具(如Docker-in-Docker) |
| 完全隔离 | --security-opt no-new-privileges |
最高 | 高合规环境、处理敏感数据 |
privileged: true。CIS Docker Benchmark建议对所有生产容器执行--security-opt=no-new-privileges:true,防止进程通过setuid/setgid二进制文件提升权限。
3.2 Linux Capabilities机制:最小权限原则的落地
Capabilities将传统root用户的超级权限拆分为独立的单元。Docker默认丢弃所有Capabilities,仅保留容器运行所需的最小集合。攻击者即使获得容器内root权限,也无法执行CAP_SYS_ADMIN(挂载文件系统)、CAP_NET_ADMIN(修改网络配置)等高危操作。
CAP_CHOWN、CAP_DAC_OVERRIDE、CAP_FOWNER、CAP_FSETID、CAP_KILL、CAP_SETGID、CAP_SETUID、CAP_SETPCAP、CAP_NET_BIND_SERVICE、CAP_NET_RAW、CAP_SYS_CHROOT、CAP_MKNOD、CAP_AUDIT_WRITE、CAP_SETFCAP。这些能力仅允许容器管理自身文件、绑定低端口、发送信号等,无法影响宿主或其他容器。
# 运行容器时仅添加必要的Capabilities
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE --cap-add=CHOWN nginx:alpine
# 在Docker Compose中配置
services:
app:
image: myapp:latest
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
- CHOWN
--cap-drop=ALL丢弃所有Capabilities,再通过--cap-add按需添加。对于不需要绑定低端口(<1024)的Web应用,甚至无需添加NET_BIND_SERVICE。定期使用capsh --print或getpcaps工具审计容器内进程的Capabilities集合。
3.3 Seccomp:系统调用级别的白名单过滤
Seccomp(Secure Computing Mode)允许Docker在容器内拦截并过滤系统调用。Docker默认提供一份“默认拒绝”的Seccomp配置文件,仅允许约300个常用系统调用,阻止约150个高危调用(如mount、kexec_load、open_by_handle_at)。
# 查看Docker默认Seccomp配置(部分内容)
{
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": ["SCMP_ARCH_X86_64"],
"syscalls": [
{
"names": ["accept", "bind", "connect", "listen", "read", "write"],
"action": "SCMP_ACT_ALLOW"
},
{
"names": ["mount", "umount2", "ptrace", "perf_event_open"],
"action": "SCMP_ACT_ERRNO"
}
]
}
strace -c -p <PID>或audit2allow工具收集应用运行时的系统调用清单,生成最小化白名单。CIS Docker Benchmark要求所有容器必须启用Seccomp,且默认配置文件不得被禁用。
# 使用自定义Seccomp配置文件运行容器
docker run --security-opt seccomp=/path/to/custom-profile.json myapp:latest
# 在Docker Compose中引用
services:
app:
image: myapp:latest
security_opt:
- seccomp:/path/to/custom-profile.json
3.4 AppArmor:强制访问控制与容器隔离
AppArmor(Application Armor)通过加载到内核的LSM(Linux Security Module)模块,为容器进程提供强制访问控制(MAC)。与Seccomp不同,AppArmor不仅限制系统调用,还能控制文件路径访问、网络协议、挂载点等资源。
| 安全机制 | 控制粒度 | 作用范围 | 配置复杂度 |
|---|---|---|---|
| Seccomp | 系统调用号+参数 | 进程系统调用 | 中 |
| AppArmor | 文件路径、网络、挂载、capabilities | 进程资源访问 | 高 |
| Capabilities | 特权操作单元 | 进程权限 | 低 |
docker-default AppArmor配置文件,该配置禁止容器写入/proc、/sys等敏感路径,并限制mount、ptrace等操作。对于高安全需求场景,应基于aa-genprof或aa-logprof工具生成自定义配置文件。
# 加载自定义AppArmor配置文件
apparmor_parser -r -W /etc/apparmor.d/docker-custom
# 运行容器时指定AppArmor配置
docker run --security-opt apparmor=docker-custom myapp:latest
# 查看当前容器关联的AppArmor配置
docker inspect --format '{{.HostConfig.SecurityOpt}}' container_name
dmesg | grep DENIED查看内核审计日志,定位被拦截的系统调用或文件访问。在开发环境可临时使用--security-opt apparmor=unconfined或--security-opt seccomp=unconfined进行调试,但严禁在生产环境使用。
3.5 运行时安全纵深防御架构
下图展示了容器运行时安全的四层纵深防御模型,从外到内依次为:AppArmor强制访问控制、Seccomp系统调用过滤、Capabilities权限裁剪、以及基础的命名空间隔离。
3.6 安全配置清单与合规检查
以下清单覆盖容器运行时安全的核心检查项,适用于CI/CD流水线中的安全门禁和定期合规审计:
- 权限控制: 禁止使用
--privileged;启用--security-opt no-new-privileges;避免以root用户运行容器(使用USER指令)。 - Capabilities: 执行
--cap-drop=ALL后按需添加;定期审计容器内进程的Capabilities集合。 - Seccomp: 启用默认Seccomp配置;高合规环境使用自定义白名单;禁用
--security-opt seccomp=unconfined。 - AppArmor: 加载并应用
docker-default或自定义配置文件;通过aa-status验证配置生效。 - 审计日志: 启用内核审计守护进程(
auditd),监控dmesg中的DENIED事件。
docker-bench-security工具自动扫描容器运行时安全配置,该工具覆盖CIS Docker Benchmark的运行时安全章节,输出通过/失败状态及修复建议。建议在CI/CD流水线中集成该工具,阻止不符合安全基线的镜像部署到生产环境。