在 linux 2.4 上以普通用户身份访问原始套接字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9772068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:15:54  来源:igfitidea点击:

raw socket access as normal user on linux 2.4

linuxsocketsraw-ethernet

提问by Chris

In an embedded system (2.4 kernel) I need raw socket access to the eth0 interface from a process notrunning as root.

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

I tried to address this problem by setting the CAP_NET_RAW capability from the command line and programmatically using cap_set_proc(), both with no success. It seems that I do not have the permission to do so, in the program I get an EPERM error, on the command line

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

Failed to set cap's on process `1586': (Operation not permitted)

无法在进程“1586”上设置上限:(不允许操作)

Is there an easier way to do what I want? If not, what steps are necessary to successfully set the CAP_NET_RAW capability?

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

EDIT: I have root access, but running the process permanently as root is no option. The version of libcap is 1.10, there is no 'setcap' binary, but a 'setpcaps'.

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

EDIT - answering George Skoptsov:

编辑 - 回答 George Skoptsov:

If I get you right, your suggestion is to start a process with setuid, then set the CAP_NET_RAW capability and then drop the privileges. I tried this with the following code, but it does not seem to work, even though the caps command do not return errors. With the seteuid() commented out, raw access works, but only since the process is running as root then:

如果我理解正确,您的建议是使用 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();

Thanks for your help. Chris

谢谢你的帮助。克里斯

采纳答案by George Skoptsov

Generally, you needroot permissions to receive raw packets on an interface. This restriction is a security precaution, because a process that receives raw packets gains access to communications of all other processes and users using that interface.

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

However, if you have access to root on the machine, you can use the setuidflag to give your process root privileges even when the process is executed as a non-root user.

但是,如果您可以访问机器上的root,即使进程以非 root 用户身份执行,您也可以使用setuid标志为您的进程授予 root 权限。

First, ensure that this capability is set successfully when the process is run as root. Then use

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

sudo chown root process
sudo chmod ugo+s process 

to set root as owner of the process and set the setuidflag. Then check that the capability is set when the process is run by other users. Because this process will now have allsuperuser privileges, you should observe security precautions, and drop the privileges as soon as your code no longer requires it (after enabling the CAP_NET_RAW).

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

You can follow this methodto ensure you're dropping them properly.

您可以按照此方法确保正确放置它们。

回答by nos

The process must be run as root, or have the CAP_NET_RAW capabilities on the executable.

该进程必须以 root 身份运行,或者在可执行文件上具有 CAP_NET_RAW 功能。

In order to set CAP_NET_RAW, you need to run the setcap command as root. Once set, you can run the executable as another user, and it'll have access to raw packet capturing.

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

If you do not have root access in anyway, nor can get anyone with root access to set CAP_NET_RAW or setuid root on the executable, you'll not be able to do packet capturing as a non-root user.

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

回答by user7119717

You can give an executable program the ability to use the CAP_NET_RAWprivilege without giving it other root privileges.

您可以赋予可执行程序使用该CAP_NET_RAW特权的能力,而无需赋予它其他 root 特权。

$ setcap cap_net_raw=pe *program*

You cannot give this privilege without having this privilege. Certainly root can give this privilege to programs.

如果没有此特权,您将无法授予此特权。当然,root 可以赋予程序这个特权。

回答by pevik

TL;DR IMHO not supported in kernel < 3.0.

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

There was a discussion about supporting it in kernel netdev mailing list: https://lwn.net/Articles/420800/and https://lwn.net/Articles/420801/.

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

And included it in commit c319b4d76b9e583a5d88d6bf190e079c4e43213d, released in kernel 3.0:

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

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

Running ping without CAP_NET_RAW (i.e. without setting capabilities or without set-uid) was implemented for ping in revision 87dbb3a5db657d5eae6934707beaf0507980a1c3, released in iputils s20150815:

在 iputils s20150815 中发布的修订版87dbb3a5db657d5eae6934707beaf0507980a1c3 中实现了在没有 CAP_NET_RAW(即没有设置功能或没有 set-uid)的情况下运行 ping :

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