容器能力机制是什么
Linux 把 root 的特权拆成一组能力(capability),如改网络配置、绑低端口、改系统时间。容器默认只保留有限的一组能力并丢弃其余,需要哪项再用 --cap-add 单独加、用 --cap-drop 明确去掉。这套按需授权的做法能避免粗暴使用 --privileged,后者会给容器全部能力、宿主设备访问并放宽 cgroup 与安全模块限制。
基本信息
| 语法 | docker run --cap-add=NET_ADMIN --cap-drop=ALL 镜像 |
|---|---|
| 默认集 | root 容器保留十几种常用能力,如 CHOWN、SETUID、NET_RAW |
| 最小授权 | --cap-drop=ALL 后只加业务确实需要的一项 |
| 非 root 用户 | 能力加在容器内 root 上,用 --user 跑普通用户时拿不到 |
| 特权模式 | --privileged 打开全部能力并放行设备,等价于宿主 root |
| 查看 | docker inspect 的 HostConfig.CapAdd/CapDrop,容器内可用 capsh --print |
典型使用场景
- 非 root 镜像要绑 1024 以下端口:只加 NET_BIND_SERVICE
- 容器内抓包或改路由:临时加 NET_ADMIN,用完立刻去掉
- 容器内校准时钟或跑依赖系统时间的工具:加 SYS_TIME
- 调试网络问题需要操作 tc、iptables:在受控环境短时授予 NET_ADMIN
- 确认某个镜像为什么会报权限不足:先查缺哪项能力,再逐项验证
使用示例
使用示例
docker run -d --cap-drop=ALL --cap-add=NET_BIND_SERVICE -p 80:80 nginx:1.27 # 仅为绑定低端口
docker run --rm --cap-add=NET_ADMIN nicolaka/netshoot tcpdump -i eth0 -c 5 # 临时抓包
docker run --rm --cap-add=SYS_TIME alpine date # 需要改时钟的工具
docker inspect --format '{{json .HostConfig.CapAdd}}' myapp # 复核实际加了哪些能力
docker exec -it myapp capsh --print # 容器内看当前进程能力集(镜像需含 libcap)常用能力对照
| 能力 | 用途 | 风险 |
|---|---|---|
| NET_BIND_SERVICE | 绑定 1024 以下端口 | 低 |
| NET_ADMIN | 改路由、抓包、配置接口 | 中,可影响整机网络视图 |
| SYS_TIME | 修改系统时钟 | 高,影响宿主时间戳相关判断 |
| DAC_OVERRIDE | 绕过文件权限读写 | 高,等于放宽文件系统边界 |
| SYS_ADMIN | 挂载与部分内核操作 | 极高,常被视为接近 root |
抓包、iptables 之类工具报权限不足时,先查具体缺哪项能力再单独加;能加一项就不要用 --privileged。
--privileged 会打开全部能力并共享宿主设备,相当于把宿主机内核暴露给容器:公网可达的业务容器不要使用。
cap-add 与 cap-drop 的处理顺序是先减后加:写出 --cap-drop=ALL 之后,必须把所需能力显式加回来;只写 --cap-add 时其余默认能力仍然保留。