为啥我不能在 Ubuntu 中创建原始套接字?
Posted
技术标签:
【中文标题】为啥我不能在 Ubuntu 中创建原始套接字?【英文标题】:Why I cant create raw socket in Ubuntu?为什么我不能在 Ubuntu 中创建原始套接字? 【发布时间】:2011-10-13 04:11:24 【问题描述】:我正在学习如何在 Linux 中使用原始套接字。我正在尝试创建一个这样的套接字:
if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
perror("socket() failed");
exit(-1);
但发布后我得到的只是:
socket() 失败:不允许操作
我知道只有 root 可以创建原始套接字,但如果我使用 SUID 位或 sudo 运行它 - 问题是一样的。怎么了?系统是Ubuntu 11.04。
也许我包含了不必要的标题?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
我想知道 - 为什么 SUID 没用?
【问题讨论】:
有趣;试图成为真正的根? (并且在执行该行之前不会删除检查的权限?) 不,我只是调用 setuid(getuid());在套接字创建之后,但它甚至没有达到。 如果你这样做:sudo bash(或 sudo 不管你使用什么shell)然后你执行程序......?有用吗? 嗯,是的,它就是这样工作的。但是为什么suid没用呢? 您是否尝试过seteuid -- 程序上的setuid位没有设置有效的uid,可能需要以编程方式设置。 【参考方案1】:我的钱是你没有正确运行你的代码。
我已将您的确切代码复制并粘贴到一个空的main()
中。如果我自己运行它,我会得到同样的错误,但它在sudo
下运行正确。这是在 Ubuntu 上。
代码:
#include <sys/socket.h>
#include <netinet/in.h>
int main()
int sd;
if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
perror("socket() failed");
return -1;
return 0;
像我自己一样奔跑:
aix@aix:~$ ./a.out
socket() failed: Operation not permitted
aix@aix:~$
以root身份运行:
aix@aix:~$ sudo ./a.out
aix@aix:~$
【讨论】:
您的代码也可以完美运行。但是我的代码与您的代码仅在标题上有所不同。我已经包含了所有这些东西(有问题添加)。 sudoers 真正能做的事情是可配置的; sudoers 的 ubuntu 11 默认是否有可能不提供真正的 root 用户? 为我节省了不少时间。非常感谢 NPE。【参考方案2】:根据 man:只有有效用户 ID 为 0 或具有 CAP_NET_RAW 能力的进程才能打开原始套接字
因此您可以按照下面的建议使用 sudo 运行您的应用程序,或者为其设置 CAP_NET_RAW 功能(实际上您也需要 CAP_NET_ADMIN):
# setcap cap_net_raw,cap_net_admin=eip PATH_TO_YOUR_APPLICATION
详情请见http://ftp.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.4/capfaq-0.2.txt
【讨论】:
【参考方案3】:无论如何标题都不会影响它。
即使您要添加更多不必要的文件,也不会影响程序的运行。
【讨论】:
以上是关于为啥我不能在 Ubuntu 中创建原始套接字?的主要内容,如果未能解决你的问题,请参考以下文章