Python非特权ICMP

29 投票
9 回答
31847 浏览
提问于 2025-04-15 13:12

在尝试找出从Python中发送ping(ICMP)请求的最佳方法时,我遇到了一些问题:

这些问题的答案通常归结为“使用这个第三方模块并需要管理员权限”或者“使用系统的ping命令并解析输出”。在原生方法中,icmplibM. Cowles和J. Diemer的ping.py明确提到需要管理员权限,scapy手册也是如此。

所以,从这一点来看,似乎在没有特殊权限的情况下,原生发送ICMP ping是不可行的。系统的ping命令似乎可以做到这一点,但它的手册并没有解释具体是怎么实现的。而icmp的手册似乎又说这是可能的:

Non-privileged ICMP
     ICMP sockets can be opened with the SOCK_DGRAM socket type without
     requiring root privileges. The synopsis is the following:

     socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP)

     Datagram oriented ICMP sockets offer a subset of the functionality avail-
     able to raw ICMP sockets. Only IMCP request messages of the following
     types can be sent: ICMP_ECHO, ICMP_TSTAMP or ICMP_MASKREQ.

所以根据icmp的说法,似乎是被允许的。那么为什么所有的Python工具都无法做到这一点呢?是因为这些Python工具太通用,认为任何需要特权的操作都必须在特权下进行吗?是否有可能在C语言中编写一个不需要管理员权限的ping函数,并将其扩展到Python中?有没有人做过这个?我是否误解了这个问题?

9 个回答

6

我不太确定在一个问题下发帖是否合适,因为这个问题似乎早就有人回答过了。

我一直在寻找相同的实现方法,发现可以用Python在不需要管理员权限的情况下进行ICMP操作。

python-ping这个库也需要管理员权限来执行ping命令,但我看到一个bug报告,里面有用户建议在调用sock时把SOCK_RAW改成SOCK_DGRAM

http://hg.io/delroth/python-ping/issue/1/icmp-without-root-privilege

开发者解释说,这种情况将会是“不会修复”的,因为这实际上是一个UDP ping。

因为我并不在乎ICMP是通过UDP发送的,所以我就拿到了代码,并做了建议的修改。

现在我可以在不调用子进程或不需要管理员权限的情况下进行ping操作了!

再次说一下,我不确定在这么久之后发帖是否合适,但我觉得这是一件好事!

14

这是关于 /sbin/ping 在大多数类Unix系统上是如何工作的:

$ ls -l /sbin/ping
-r-sr-xr-x  1 root  wheel  68448 Jan 26 10:00 /sbin/ping

看到了吗?它的拥有者是 root,而且权限中有一个重要的 s 位,叫做设置用户ID。所以,不管哪个用户在运行它,ping 都是以root身份运行

如果你使用的是BSD内核,并且有新的“非特权ICMP套接字”,那么了解如何用Python利用这个功能来ping会很有趣(不过这对使用较老内核的用户就没什么帮助了)。

15

ping程序是以root身份安装的,这样任何用户都可以使用这个程序,并且能够打开一个原始套接字。

在打开原始套接字之后,它通常会放弃root权限。

要正确使用ICMP,通常需要一个原始套接字,而原始套接字通常是有限制的。所以这并不是python的问题。

关于上面提到的ICMP,显然很多实现并不太支持那些标志的组合。因此,大多数实现可能只是使用他们“知道”的在大多数或所有架构上有效的方法。

撰写回答