Linux Capability机制将root权限细分为独立能力单元,按需授予进程或文件以实现最小特权原则;例如监听80端口只需CAP_NET_BIND_SERVICE,而非赋予宽泛的CAP_SYS_ADMIN等权限。

Linux 权限加固不能只靠禁用 root 或删 sudo,关键在于把“该给的权给准、不该给的权锁死”。Capability 机制正是实现这一目标的核心手段——它不依赖 UID 切换,而是直接控制内核对特定系统调用的放行,让进程只拥有完成任务所必需的那一小块特权。
明确服务真实需求,避免能力滥用
盲目添加 CAP_SYS_ADMIN、CAP_NET_ADMIN 等宽泛能力,等于主动打开提权后门。必须结合服务实际行为判断所需能力:
- 监听 80/443 端口 → 只需 CAP_NET_BIND_SERVICE,无需 root 身份
- 发送原始网络包(如 ping、tcpdump)→ 需 CAP_NET_RAW,若还需设混杂模式才加 CAP_NET_ADMIN
- 修改系统时间 → 单独赋予 CAP_SYS_TIME,不连带授予挂载或进程调试权限
- 挂载文件系统 → 优先用 user namespace 或 bind mount 替代;确需时再给 CAP_SYS_ADMIN,并限制挂载路径和 fstype
用 setcap 精准绑定能力到可执行文件
能力应固化在二进制文件上,而非运行时动态开启,这样更稳定、更易审计:
- 赋予绑定低端口能力:sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/myserver
- 仅允许子进程继承(不立即生效):sudo setcap cap_net_raw=i /usr/local/bin/packet-tool
- 同时设置多个能力:sudo setcap 'cap_sys_admin,cap_dac_override=+ep' /usr/local/bin/backup-tool
- 查看是否生效:getcap /usr/local/bin/myserver(输出含 =cap_net_bind_service+ep 即成功)
注意:setcap 不作用于 shell 脚本(内核不解析 shebang 后的能力),也不影响 noexec 挂载点上的文件。
用 inheritable 控制子进程权限传递
主进程高权启动后,工作子进程不应自动继承全部能力。通过 cap_inheritable 实现父子权限隔离:
- 启动时限制可继承集:capsh --inh=cap_net_bind_service -- -c "nginx -g 'daemon off;'"
- 子进程 exec 新程序时,其 permitted 能力 = 父进程 inheritable ∩ 可执行文件的 inheritable 位
- 验证继承效果:在容器或 systemd 服务中启用 AmbientCapabilities 和 CapabilityBoundingSet,防止能力意外扩散
容器与守护进程中的最小化实践
在容器或 systemd 服务中,能力控制要更进一步:
- Docker/Podman 启动时从 --cap-drop=ALL 起步,再按需添加,例如:docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
- systemd 服务配置中禁用高危能力:CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_AUDIT_WRITE
- 配合 NoNewPrivileges=true 和 PrivateTmp=true,阻断隐式提权路径
- 用 capsh --print 在运行环境中实时验证当前生效能力集,确认无冗余项


















