2012-03-19 21 views
9

在嵌入式系统(2.4内核)中,我需要原始套接字从进程而不是以root用户身份访问eth0接口。作为Linux上的普通用户的原始套接字访问2.4

我试图通过在命令行中设置CAP_NET_RAW功能并使用cap_set_proc()编程方式解决此问题,但两者均未成功。看来,我没有这样的权限,在程序中我得到一个EPERM错误,命令行

无法设置上限的工艺'1586' 上:(不允许的操作)

有没有更简单的方法来做我想要的?如果没有,成功设置CAP_NET_RAW功能需要执行哪些步骤?

编辑:我有根访问权限,但永久运行该进程作为根目录是没有选择。 libcap的版本是1.10,没有'setcap'二进制文件,但是'setpcaps'。

编辑 - 乔治回答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

+0

如果你按照我的建议下面,你的过程将不会运行但是在启动时将拥有root权限,这将允许它设置所需的功能。 – 2012-03-20 15:24:57

+0

感谢您的建议乔治,但是,我没有成功......看到我的编辑。 – Chris 2012-03-21 07:37:09

+0

Chris,在'function_that_needs_raw_access()'中显式需要时你可以非常小心地提升权限? – 2012-03-23 12:27:40

回答

6

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

但是,如果你有机会到根的机器上,你可以使用setuid标志,让您的过程root权限即使方法作为非root用户执行。

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

sudo chown root process 
sudo chmod ugo+s process 

将根设置为进程的所有者并设置setuid标志。然后检查该进程是否由其他用户运行时设置的功能。由于此过程现在将具有全部超级用户权限,因此您应遵守安全防范措施,并在代码不再需要时立即删除权限(启用CAP_NET_RAW后)。

您可以按照this method确保您正确放下它们。

+0

我不知道如何启用CAP_NET_RAW。没有setcap命令。当使用setuid标志运行进程时一切正常,但我不想以超级用户身份运行进程... – Chris 2012-03-20 15:24:43

+0

您不是以超级用户身份运行进程。您可以在完成设置功能后立即放弃这些权限,这些权限在root下运行。 – 2012-03-20 15:28:15

+0

我原来的问题并没有真正解决,但我接受这个答案,因为乔治试图帮助我,这是“最接近”的解决方案。 – Chris 2012-04-05 11:54:35

3

该进程必须以超级用户身份运行,或者对可执行文件具有CAP_NET_RAW功能。

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

如果您无论如何都不具有root用户访问权限,也无法让任何拥有root权限的用户在可执行文件上设置CAP_NET_RAW或setuid root,您将无法以非root用户的身份执行数据包捕获。

+0

没有setcap命令,只有setpcaps。我试图以root身份运行setpcaps来设置正在运行的进程的大写,但这不起作用(请参阅原始文章中的错误消息)。 – Chris 2012-03-20 15:09:07

1

您可以为可执行程序提供使用CAP_NET_RAW权限而无需授予其他root权限的功能。

$ setcap cap_net_raw=pe *program* 

如果您没有此权限,您不能授予此权限。当然,root可以赋予程序这种特权。

+0

Linux下'2.6.24'没有文件功能。这就是问题所在。 – 2016-11-05 17:26:07

0

TL; DR恕我直言内核不支持< 3.0。

有关于在内核netdev邮件列表中支持它的讨论: https://lwn.net/Articles/420800/https://lwn.net/Articles/420801/

并已将其列入提交 c319b4d76b9e583a5d88d6bf190e079c4e43213d,在内核3.0发布:

commit c319b4d76b9e583a5d88d6bf190e079c4e43213d 
Author: Vasiliy Kulikov <[email protected]> 
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 

没有CAP_NET_RAW运行ping(即不设置能力或没有设定UID)是为平在修订实施87dbb3a5db657d5eae6934707beaf0507980a1c3 ,发布在iputils s20150815:

commit 87dbb3a5db657d5eae6934707beaf0507980a1c3 
Author: Nikos Mavrogiannopoulos <[email protected]> 
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