封住提权路径
no-new-privileges 让容器内的进程无法通过 setuid、setgid 或文件能力获得比当前更高的权限:镜像里即使存在带 SUID 位的程序,也拿不到额外权限。它挡住的是「拿到普通用户后借系统程序提权」这条常见路径,代价极低,对普通业务几乎没有感知,适合作为容器标准配置的一部分统一开启。
基本信息
| 参数 | --security-opt no-new-privileges=true |
|---|---|
| 守护层默认 | daemon.json 里可配置为全局默认 |
| 核对字段 | docker inspect 的 HostConfig.SecurityOpt |
| 作用范围 | 阻止提权路径,不改变进程现有的权限 |
典型使用场景
- 生产基线统一开启:一条参数覆盖所有无状态服务
- 配合非 root 用户:权限与提权双重收紧
- 加固验收核对:检查 SecurityOpt 里是否包含该条目
- 临时验证影响:先在一台机器上全局开启,观察业务是否受影响
- 镜像审计后的兜底:即使镜像里留有 SUID 程序,也拿不到额外权限
开启与核对
开启与核对
# 启动时开启
docker run -d --name api --security-opt no-new-privileges=true app/api:1.4.2
# 核对配置已经写入
docker inspect -f '{{json .HostConfig.SecurityOpt}}' api
# 验证提权被阻断:找一个带 SUID 位的程序试运行
# docker exec api sh -c 'find / -perm -4000 -type f 2>/dev/null | head'
# 全局默认:daemon.json 里加 no-new-privileges 为 true 后重载守护进程常见加固项对照
| 选项 | 作用 | 代价 |
|---|---|---|
| no-new-privileges | 禁止通过 SUID 与文件能力提权 | 极少数依赖 SUID 的老应用受影响 |
| cap-drop 加 cap-add | 把内核能力收缩到必要集合 | 需要逐个功能验证 |
| read-only | 根文件系统只读 | 要额外放开必要的可写目录 |
| 非 root 用户运行 | 降低进程初始权限 | 镜像内目录属主需要调整 |
该选项与特权模式语义冲突:特权容器本身就放弃了这层约束,两者同时使用等于没有加固。
它解决的是提权路径而不是全部风险:应用自身的漏洞、配置错误与网络暴露仍需按各自方向治理。
验证是否生效的简单办法:在容器里找一个带 SUID 位的程序执行,看能否获得超出当前身份的权限;也可以直接读 /proc/self/status 里的 NoNewPrivs 字段,值为 1 表示已开启。