docker设备白名单需通过daemon.json中device-cgroup-rules配置cgroup规则实现,格式为"type:major:minor acc",配合设备权限控制、非privileged模式及cap_drop等机制构成纵深防御。
docker compose 本身不支持设备白名单机制,daemon.json 也不能直接配置“容器设备白名单”。真正能实现设备级访问控制的,是 docker daemon 启动时通过 --device-cgroup-rule 参数注入的 cgroup 设备白名单规则——它作用于整个 docker 守护进程,对所有容器生效,属于内核级强制策略。
为什么 daemon.json 里没有 devices-whitelist 字段?
Docker 的设备访问模型是「默认放行 + 显式挂载」:只要容器能读取 /dev 下的设备节点(权限允许),且未被 cgroup 限制,它就可能打开该设备。docker-compose.yml 中的 devices: 只是声明挂载,不是过滤器;而 daemon.json 是 daemon 全局配置文件,它不定义 per-container 白名单,只提供统一的设备访问基线控制。
正确做法:在 daemon.json 中启用 device-cgroup-rule
编辑 /etc/docker/daemon.json,添加 default-runtime 和 runtimes(如需 GPU 支持),并关键配置 device-cgroup-rules:
- 该字段仅在 Docker 20.10+ 版本中支持(需确认
docker version) - 每条规则格式为:
"TYPE:MAJOR:MINOR ACC",例如"c 8:* rmw"表示允许所有 SCSI 块设备(主号 8)的读、写、mknod - 规则按顺序匹配,
a *:* rmw表示“全部放行”,应放在最后;前面的规则用于显式放行必需设备 - 必须配合
"default-ulimits": {"nofile": {"Hard": 65536, "Soft": 65536}}等基础加固项使用
示例(仅允许容器访问 /dev/video0、GPU 渲染节点和标准终端):
必须同步做的宿主机层面动作
仅改 daemon.json 不生效,还需:
- 确保对应设备节点权限严格:如
sudo chmod 600 /dev/video0 && sudo chown root:video /dev/video0,再将容器用户加入video组 - 重启 Docker:运行
sudo systemctl daemon-reload && sudo systemctl restart docker - 验证规则是否加载:执行
cat /sys/fs/cgroup/devices/docker/*/devices.list | head -5,查看子 cgroup 白名单内容 - 容器启动时禁用特权:
privileged: false(默认值),且不挂载/dev整体
补充建议:组合安全机制才可靠
设备白名单只是纵深防御的一环,建议与以下配置协同使用:
-
cap_drop: ["ALL"]—— 移除所有 capabilities,防止绕过设备节点权限 -
security_opt: ["no-new-privileges:true"]—— 阻止 setuid 程序提权后重新获取设备访问能力 - 配合 seccomp profile 禁用
openat、ioctl等敏感调用(尤其针对摄像头/GPU) - 使用 AppArmor 或 SELinux 策略进一步约束设备路径访问行为











