docker compose 无原生设备白名单机制,仅通过 devices 字段显式挂载授权设备;真正设备访问控制依赖宿主机 /dev 权限、device-cgroup-rule 全局白名单、cap_drop、no-new-privileges 及 seccomp 等内核级机制协同实现。

Docker Compose 本身不提供设备白名单或硬件级访问控制机制,它无法直接限制容器“越权查看硬件”(如摄像头、GPU、USB设备等)。这类控制依赖于底层 Linux 的设备节点权限、cgroup、seccomp、AppArmor/SELinux 等机制,而 docker-compose.yml 仅能声明容器希望访问哪些设备(通过 devices 字段),属于“显式授权”,而非“白名单过滤”。
真正起作用的是:
✅ 宿主机上 /dev/ 下设备节点的文件权限(ls -l /dev/video0)
✅ Docker daemon 启动时是否启用 --device-cgroup-rule(需手动配置 dockerd)
✅ 容器是否以 privileged: false(默认)运行,且未挂载无关设备
✅ 是否配合 security_opt(如 seccomp profile)禁用敏感系统调用
✅ 正确做法:在 docker-compose.yml 中「最小化设备暴露」
只挂载容器真正需要的设备,并确保宿主机设备权限严格:
version: '3.8'
services:
myapp:
image: ubuntu:22.04
devices:
- "/dev/video0:/dev/video0:r" # 仅读取摄像头,不写入
- "/dev/dri/renderD128:/dev/dri/renderD128:r" # 仅 GPU 渲染节点(非 controlD64)
cap_drop:
- ALL
security_opt:
- "no-new-privileges:true"
read_only: true
tmpfs:
- /tmp
? 说明:
/dev/video0:r表示只读挂载;cap_drop: ALL移除所有 Linux Capabilities;no-new-privileges阻止提权。
✅ 宿主机层面加固(必须配合)
Docker 默认允许容器访问任意设备(只要路径存在且权限允许)。要实现“设备白名单”,需在 Docker daemon 配置中添加设备 cgroup 规则:
在 /etc/docker/daemon.json 中添加:
使用 Python 脚本下载 Docker 镜像并打包为 tar 文件。用户说“下载镜像”“拉取镜像”“pull xxx”“帮我下载 nginx 镜像”等时触发。支持 SOCKS5 代理直连(推荐)和国内镜像站加速两种模式。
{
"default-runtime": "runc",
"runtimes": {
"runc": {
"path": "runc"
}
},
"device-cgroup-rule": "b 8:* rmw", // 允许所有块设备(如 /dev/sda)读写管理
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 65536,
"Soft": 65536
}
}
}
⚠️ 注意:device-cgroup-rule 是全局白名单规则(格式:<type><major>:<minor><access></access></minor></major></type>),支持 b(block)、c(char),r/w/m(读/写/mknod)。
例如限制只允许访问 video0(主设备号 81,次设备号 0):
"device-cgroup-rule": "c 81:0 r"
但需先查清设备号:ls -l /dev/video0 → 输出类似 crw-rw---- 1 root video 81, 0 Apr 10 10:00 /dev/video0
✅ 进阶:结合 udev + cgroup v2 + seccomp
- 使用
udev规则动态设置设备权限(如仅允许特定用户组访问/dev/video*) - 启用 cgroup v2 并在
dockerd启动参数中加--cgroup-manager systemd - 自定义 seccomp profile,屏蔽
ioctl调用中涉及设备枚举的命令(如VIDIOC_QUERYCAP)
示例 seccomp 禁用设备查询(保存为 deny-video-ioctl.json):
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": ["ioctl"],
"action": "SCMP_ACT_ERRNO",
"args": [
{
"index": 1,
"value": 563297280, // VIDIOC_QUERYCAP (hex: 0x21900000)
"valueTwo": 0,
"op": "SCMP_CMP_EQ"
}
]
}
]
}
然后在 compose 中引用:
security_opt: - "seccomp:/path/to/deny-video-ioctl.json"
❌ 常见误区
- 认为
devices:字段本身是白名单 —— 它只是“挂载列表”,不是访问控制开关 - 忽略宿主机
/dev权限,导致容器用root身份轻易访问其他设备 - 未
cap_drop或留着NET_ADMIN、SYS_ADMIN等能力,使容器可自行mknod创建设备节点 - 在
privileged: true模式下谈设备白名单 —— 此时所有设备自动可访问,规则全部失效
不复杂但容易忽略。










