程序无法获取所需的功能(原始套接字)

程序无法获取所需的功能(原始套接字)

注意:这部分是一个编程问题,但我的直觉是这与 Linux 的安全功能框架有更多关系一般来说,因此在这里发布而不是 StackOverflow。

我有一个程序需要使用cap_net_raw原始套接字和数据包捕获功能;我使用的系统是 Debian 11 和 Linux 5.16.0-6-amd64。

cap_net_admin我已向二进制文件授予了功能 (with )

% sudo /sbin/setcap 'cap_net_raw,cap_net_admin+eip' ./program

(旁注:我已授予我的用户cap_setfcap中的功能,但如果没有 sudo/etc/security/capability.conf我仍然无法)setcap

并确认至少几乎按照要求应用了上限

% /sbin/getcap ./program
./program cap_net_admin,cap_net_raw=eip

capsh --print我的用户显示的 bash 运行的输出

% /sbin/capsh --print
Current: cap_setpcap,cap_net_admin,cap_net_raw,cap_sys_ptrace,cap_setfcap=i
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,cap_perfmon,cap_bpf,cap_checkpoint_restore
Ambient set =
Current IAB: cap_setpcap,cap_net_admin,cap_net_raw,cap_sys_ptrace,cap_setfcap
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
 secure-no-ambient-raise: no (unlocked)
uid=1001(johndoe) euid=1001(johndoe)
gid=1001(johndoe)
groups=27(sudo),1001(johndoe)
Guessed mode: UNCERTAIN (0)

现在;我可以毫无问题地与我的用户运行 ping。在 Debian 上 ping 似乎具有能力感知能力,即二进制文件具有所需的能力

% /sbin/getcap `which ping`
/usr/bin/ping cap_net_raw=ep

并从ping源代码(https://sources.debian.org/src/iputils/3%3A20210202-1/ping/ping.c/)我发现运行时的功能没有提升。即文件功能足以使其按预期工作。我的结论是,只要可执行文件具有适当的功能,我的程序就应该同样运行良好。

但似乎并非如此。我已为程序文件设置了所需的(据我所知)功能,但是当我运行它时,套接字创建失败,并显示EPERM.

调试进程并在套接字创建时中断并检查进程功能表明该进程不具备有效的所需功能:

 % grep Cap /proc/`pidof program`/status                     
CapInh: 0000000080083100
CapPrm: 0000000000000000
CapEff: 0000000000000000 
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000

检查CapInhCapBndwithcapsh --decode=...显示这些位符合预期(与之前的capsh --print输出匹配)。但是允许集和有效集(CapPrmCapEff分别)并不是我所期望的(也许我的例外完全是错误的)。我假设允许的集合有cap_net_rawcap_net_admin

为了解决这种情况,我尝试cap_net_raw在创建套接字之前在程序中启用:

cap_value_t needed[] = { CAP_NET_RAW };
cap_t caps = cap_get_proc();

cap_set_flag(caps, CAP_EFFECTIVE, std::size(needed), needed, CAP_SET);
if (cap_set_proc(caps))
{
    // handle failure
}

EPERM但正如现在“预期的”那样,这悲惨地失败了( )。也尝试将位添加到第一个中,但该修改CAP_PERMITTED的结果再次是。cap_set_proc()EPERM

我在这里错过了什么或误解了什么?为了为我的程序启用原始套接字访问,我还需要做什么?

与其他系统相比,Debian 11 是否有更严格的规则和限制?

仅供参考:我检查了我可以使用的 Raspberry Pi OS (Debian 10) 系统,报告capshpi用户的Current设置与设置相同Bounding(根本没有Ambient设置)。 Afaik,系统默认运行,所以我的结论是 Raspberry Pi OS/Debian 10 在功能方面默认具有更允许/宽松的安全模型。

这与命名空间有关系吗?文件所有权/权限?

相关内容