咨询实现tap设备创建、裸套接字绑定及IPv6禁用所需Linux权限
非root运行测试:修改IPv6禁用配置的Linux权限问题
问题描述
编写大型程序测试用例时需完成三项操作:
- 创建tap设备
- 绑定裸套接字
- 修改sysctl禁用指定网卡的IPv6(执行
echo 1 > /proc/sys/net/ipv6/conf/$if/disable_ipv6)
前两项已确认需要CAP_NET_ADMIN和CAP_NET_RAW权限,但第三项尝试添加CAP_SYS_ADMIN和CAP_DAC_OVERRIDE后仍无法执行,需找到正确权限配置。
测试情况补充
已为测试程序添加以下能力:
$ getcap ./target/debug/deps/tap_tests-e43c717a6e86b805 ./target/debug/deps/tap_tests-e43c717a6e86b805 cap_net_admin,cap_net_raw,cap_sys_admin=eip
运行测试时仍报错:
--- test_conntrack_active_probe stdout ---- thread 'test_conntrack_active_probe' panicked at 'safe_run_command FAILED: 'sysctl -w net.ipv6.conf.testtap1.disable_ipv6=1' command returned stderr 'Ok( "sysctl: permission denied on key \"net.ipv6.conf.testtap1.disable_ipv6\" ", )'', tests/tap_tests.rs:275:13
调试方法分享
为追踪权限问题,可让strace继承测试程序的能力,操作如下:
$ cp `which strace` ./strace $ setcap CAP_NET_ADMIN=epi ./strace $ ./strace -f <test> # 普通strace不会继承测试程序的文件能力
核心原因与解决方法
问题根源在于exec调用时的文件能力继承规则:Linux中,通过setcap设置的文件能力不会通过exec传递给子进程。测试程序调用外部sysctl命令时,子进程未继承父进程的CAP_NET_ADMIN权限,导致操作失败。
实际修改网卡IPv6禁用状态仅需CAP_NET_ADMIN权限,解决思路有两种:
- 程序内直接操作proc文件:不要调用外部
sysctl命令,在测试代码中直接打开/proc/sys/net/ipv6/conf/$if/disable_ipv6文件并写入"1",利用当前进程的CAP_NET_ADMIN权限完成操作。 - 给外部命令添加能力:若必须调用
sysctl,可给sysctl二进制文件添加CAP_NET_ADMIN能力,或使用capsh等工具在执行命令时保留所需权限。
内容的提问来源于Stack Exchange,提问作者capveg
相关产品推荐
相关产品推荐

