【发布时间】:2021-04-20 02:09:42
【问题描述】:
我有一个包装程序,它仅用于将CAP_NET_RAW 功能添加到 nodejs 脚本。该二进制文件已将功能设置为cap_net_raw+eip,但该进程没有获取它们并且设置它们会导致EPERM (Operation not permitted)。从 Debian 9 升级到 10 后,包装器停止工作。向 nodejs 二进制文件添加功能可以工作,并且 nodejs 脚本运行良好,但不希望允许对任何 nodejs 脚本的网络适配器进行原始访问。
这是包装源代码:
#include <sys/capability.h>
#include <unistd.h>
void main() {
cap_t caps = cap_get_proc();
cap_value_t newcaps[1] = { CAP_NET_RAW, };
cap_set_flag(caps, CAP_INHERITABLE, 1, newcaps, CAP_SET);
cap_set_proc(caps);
cap_free(caps);
execl("/usr/bin/node", "node", "/opt/sitemp/sitemp.js", NULL);
}
在 strace 下运行结果如下:
capget({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, NULL) = 0
capget({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, {effective=0, permitted=0, inheritable=0}) = 0
capset({version=_LINUX_CAPABILITY_VERSION_3, pid=0}, {effective=0, permitted=0, inheritable=1<<CAP_NET_RAW}) = -1 EPERM (Operation not permitted)
【问题讨论】:
-
我已经通过在 systemd.service 中分配功能而不是自定义包装器/二进制文件来解决我的问题。 Systemd 服务具有属性
AmbientCapabilities用于精确此 -
Linux 内核不信任具有文件权限的脚本,只信任已编译的二进制文件。如果您尝试制作
sitemp.jssetuid-root,也会出现同样的问题。 -
权限设置在二进制文件上,而不是脚本上。此设置在 Debian 9 中有效,但在 10 中无效。
-
与其试图在这里解释,我会发布一个更完整的答案......
标签: c linux linux-capabilities