linux capability继承需同时满足:父进程cap_inheritable含该能力、可执行文件设i标志、未被cap_bset屏蔽;用setcap配置文件i标志,capsh可临时控制,cat /proc/self/status验证实际继承状态。

Linux 的 Capability 继承控制,核心在于让子进程只拿到它真正需要的那部分权限,而不是一股脑继承父进程的全部能力。关键不在“给多少”,而在“传什么、怎么传、谁允许传”。
cap_inheritable 是权限传递的开关
它本身不直接赋予任何执行权限,而是决定:当父进程调用 execve() 启动新程序时,哪些能力可以“带过去”。子进程能否获得某项能力,取决于三个条件同时满足:
- 父进程的
cap_inheritable集合中包含该能力 - 被 exec 的可执行文件自身的
cap_inheritable位也开启(即文件能力中含i标志) - 该能力未被系统
cap_bset(capability bounding set)屏蔽
三者缺一不可。例如,父进程设置了 cap_net_raw+i,但目标程序没用 setcap cap_net_raw=i /path/to/tool 配置,那子进程就拿不到这个能力。
设置文件的可继承能力
用 setcap 命令把 i(inheritable)标志加到可执行文件上:
-
sudo setcap cap_net_bind_service=i /usr/local/bin/myserver→ 允许该程序在 exec 时被继承绑定低端口的能力,但自身启动时不自动启用 -
sudo setcap cap_sys_admin,cap_dac_override=ip /usr/local/bin/backup-tool→ 同时设两个能力为 inheritable(i)和 permitted(p),常用于工具类子进程 - 查看是否生效:
getcap /usr/local/bin/myserver,输出含=i或=ip即表示配置成功
运行时控制继承行为
不改文件也能临时控制继承路径,适合调试或容器启动场景:
-
capsh --inh=cap_net_raw -- -c "/usr/local/bin/packet-sniffer"→ 启动 shell 时预设cap_net_raw在 inheritable 集合中,后续 exec 的程序若自身支持该能力,即可继承 -
capsh --drop=all --inh=cap_chown --caps="cap_chown+eip" -- -c "chown user:group file"→ 清空所有能力后,仅保留cap_chown并设为 inheritable + effective + permitted,精准完成操作 - 注意:这种设置只对当前 shell 及其子进程有效,退出即失效
验证继承是否生效
别只看文件配置,要确认子进程实际拿到的能力:
- 在子进程中调用
capget()或使用命令行工具:cat /proc/self/status | grep Cap关注CapInh(inheritable)、CapPrm(permitted)、CapEff(effective)三行十六进制值 - 用
capsh --print快速查看当前 shell 的完整能力状态 - 常见误区:子进程
CapPrm为空 ≠ 文件没设能力,很可能是父进程没开i,或目标文件没配i,或cap_bset拦截了











