Linux原始套接字权限问题

我正在C应用程序中创build一个原始的以太网套接字,例如

s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 

并返回-1表示错误

我很确定它的权限问题 – 只有你有一个UID为0(root)或者具有CAP_NET_RAW能力的情况下,你才能打开一个原始套接字

我不认为以root身份运行应用程序是合理的,因此我的问题是如何将CAP_NET_RAWfunction权限添加到我的用户帐户?

从http://manpages.ubuntu.com/manpages/zesty/en/man7/packet.7.html

  In order to create a packet socket, a process must have the CAP_NET_RAW capability in the user namespace that governs its network namespace. 

但是,如何实现这一目标呢?

您在需要该功能的可执行文件上设置功能,而不是用户帐户。 语法是

 setcap cap_net_raw,cap_net_admin=eip ./your_exeutable 

(注意,你需要以root身份运行setcap,所以使用例如sudo setcap ...还要确保sudo setcap ...中没有空格字符cap_net_raw,cap_net_admin=eip

能够读取所有网络数据包被认为是一个严重的安全风险,这就是为什么这需要一个特权帐户。

您可以使应用程序“suid root”以“普通”用户身份启动此应用程序时提升自己的权限。 但是这也是一个安全风险,在设计应用程序的时候需要一些彻底的思考(一旦不需要它,至少应该放弃更高的权限 – 即打开原始套接字后)。

您不能将CAP_NET_RAW权限添加到您的帐户,因为Linux上的功能不跟随用户。 他们遵循可执行文件。

要做到这一点,需要将CAP_NET_RAW功能添加到编译好的可执行文件中。 请参阅setcap命令以了解如何执行此操作。