linux 2.4上普通用户的原始套接字访问

linux 2.4上普通用户的原始套接字访问,linux,sockets,raw-ethernet,Linux,Sockets,Raw Ethernet,在嵌入式系统(2.4内核)中,我需要从一个不以root身份运行的进程对eth0接口进行原始套接字访问 我试图通过从命令行设置CAP_NET_RAW功能和以编程方式使用CAP_set_proc()来解决这个问题,但都没有成功。似乎我没有这样做的权限,在程序中,我在命令行上得到一个EPERM错误 未能在进程“1586”上设置cap:(不允许操作) 有没有更简单的方法来做我想做的事?如果没有,则需要哪些步骤才能成功设置CAP_NET_原始功能 编辑:我有root访问权限,但不能以root身份永久运行进

在嵌入式系统(2.4内核)中,我需要从一个不以root身份运行的进程对eth0接口进行原始套接字访问

我试图通过从命令行设置CAP_NET_RAW功能和以编程方式使用CAP_set_proc()来解决这个问题,但都没有成功。似乎我没有这样做的权限,在程序中,我在命令行上得到一个EPERM错误

未能在进程“1586”上设置cap:(不允许操作)

有没有更简单的方法来做我想做的事?如果没有,则需要哪些步骤才能成功设置CAP_NET_原始功能

编辑:我有root访问权限,但不能以root身份永久运行进程。libcap的版本是1.10,没有“setcap”二进制文件,而是“setpcaps”

编辑-回答George Skoptsov:

如果我没弄错的话,你的建议是用setuid启动一个进程,然后设置CAP_NET_RAW功能,然后放弃特权。我用下面的代码尝试了这一点,但它似乎不起作用,即使caps命令不返回错误。在seteuid()被注释掉后,原始访问可以工作,但只有当进程以root用户身份运行时,才能工作:

cap_t caps = cap_get_proc();
cap_value_t cap_list[1];
cap_list[0] = CAP_NET_RAW;
if (cap_set_flag(caps, CAP_EFFECTIVE, 1, cap_list, CAP_SET) == -1)
{
    printf("cap_set_flag error");
}
if (cap_set_proc(caps) == -1)
{
    printf("cap_set_proc error");
}

if (seteuid(getuid()) != 0) 
{
    printf("seteuid error");
}

function_that_needs_raw_access();
谢谢你的帮助。
Chris

通常,您需要root权限才能在接口上接收原始数据包。此限制是一种安全预防措施,因为接收原始数据包的进程可以访问使用该接口的所有其他进程和用户的通信

但是,如果您有权访问计算机上的root用户,则即使在以非root用户身份执行进程时,也可以使用该标志授予进程root权限

首先,确保在以root用户身份运行进程时成功设置此功能。然后使用

sudo chown root process
sudo chmod ugo+s process 
将root设置为进程的所有者并设置
setuid
标志。然后检查在其他用户运行该进程时是否设置了该功能。由于此进程现在将拥有所有超级用户权限,因此您应该遵守安全预防措施,并在代码不再需要权限时(启用CAP_NET_RAW后)立即放弃该权限


您可以按此操作,以确保正确删除它们。

该进程必须以root用户身份运行,或者在可执行文件上具有CAP\u NET\u RAW功能

为了将CAP_NET_设置为RAW,您需要以root用户身份运行setcap命令。一旦设置好,您就可以作为另一个用户运行可执行文件,并且它可以访问原始数据包捕获


如果您在任何情况下都没有root访问权限,也无法让任何具有root访问权限的人在可执行文件上设置CAP_NET_RAW或setuid root,您将无法作为非root用户进行数据包捕获。

您可以赋予可执行程序使用
CAP_NET_RAW
权限,而无需授予其其他root权限

$ setcap cap_net_raw=pe *program*

没有此权限,您不能授予此权限。当然,root用户可以将此特权授予程序。

TL;内核<3.0中不支持DR IMHO。

在内核netdev邮件列表中讨论了如何支持它: 和

并将其包含在提交中 ,在内核3.0中发布:

commit c319b4d76b9e583a5d88d6bf190e079c4e43213d
Author: Vasiliy Kulikov <segoon@openwall.com>
Date:   Fri May 13 10:01:00 2011 +0000

    net: ipv4: add IPPROTO_ICMP socket kind

Follows: v2.6.39-rc2
Precedes: v3.0-rc1
提交c319b4d76b9e583a5d88d6bf190e079c4e43213d
作者:瓦西里·库利科夫
日期:2011年5月13日星期五10:01:00+0000
net:ipv4:添加IPPROTO_ICMP套接字类型
如下:v2.6.39-rc2
前置版本:v3.0-rc1
在iputils s20150815中发布的版本中,为ping执行了无CAP_NET_RAW(即无设置功能或无设置uid)的ping:

commit 87dbb3a5db657d5eae6934707beaf0507980a1c3
Author: Nikos Mavrogiannopoulos <nmav@redhat.com>
Date:   Fri May 29 11:01:00 2015 +0200

    This patch allows running ping and ping6 without root privileges on
    kernels that support it. Almost identical to Lorenzo
    Colitti's original patch except:
    ...

Follows: s20140519
Precedes: s20150815
提交87DBB3A5DB657D5EAE693707BEAF0507980A1C3
作者:Nikos Mavrogiannopoulos
日期:2015年5月29日星期五11:01:00+0200
此修补程序允许在没有根权限的情况下运行ping和ping6
支持它的内核。几乎和洛伦佐一样
科利蒂的原始补丁,除了:
...
如下:s20140519
之前:s20150815

没有setcap命令,只有setpcaps。我曾尝试以root用户身份运行setpcaps来为正在运行的进程设置上限,但这不起作用(请参阅原始帖子中的错误消息)。我不知道如何启用CAP\u NET\u RAW。没有setcap命令。当使用setuid标志运行进程时,一切正常,但我不想以root身份运行进程…您不是以root身份运行进程。您可以在设置完功能后立即删除这些权限,这在root下对您有效。我最初的问题没有真正解决,但我接受这个答案,因为George试图帮助我,这是“最接近”的解决方案。@Chris这是权限问题的真正解决方案。。。只要遵循基本规则:1<代码>chmod a+s程序文件,2<代码>/procfile作为普通用户,3。在
procfile
do
setuid(0)
中成为root,4。做任何需要特权的事情(小心,最好不要在这里接受用户输入),5。再次执行
setuid(普通用户)
以删除根权限,6。正常继续程序。(请记住setuid()可能无法从脚本中工作,我的代码只是伪代码,用于显示正确操作的简单步骤)如果您遵循下面的建议,您的进程将不会以root身份运行,但在启动时将具有root权限,这将允许它设置您想要的功能。不过,感谢您的建议,我没有成功。。。查看我的编辑。Chris,如果在需要原始访问()的
函数中明确需要升级权限,您可能会非常小心。linux
2.6.24
下没有文件功能。这就是问题所在。