Python – a good way to run ICMP ECHO requests from a Python script

permissionspingpython

I'm maintaining an application (written in Python) which polls information of a large number of hosts. As input I have a set of network ranges. Not all of the hosts in those ranges are always up. For the hosts which are down, I run into incredibly long TCP timeouts.

For this reason, I run an nmap fast ping-scan before the main application executes.

This means that the application has a dependency on nmap being installed on the system. All for only a simple ping-check.

The problem is that, as a normal user, I am not privileged enough to send out ICMP ECHO requests. Both nmap and ping have the setuid bit set IIRC. So those can be run as normal user.

Given that I write my own application, which is also a Python script which runs through the Python interpreter, I wonder what the best possibility is to run ICMP requests from there.

Setting the setuid bit on the Python interpreter seems like a sledge-hammer solution.

Note that the application runs as a separate user and from a Python virtual environment (in case that would make a difference).

Best Answer

You can give your script the ability to use the CAP_NET_RAW privilege without running it as root. This privilege is required to use RAW sockets which are required to send ping echo requests. You can try:

$ sudo setcap cap_net_raw+pe <your_script>

To be honest, I did not try it myself. It seems like it will not be effective if you do it on a script that will be executed by an interpreter. Here is a relevant post on unix stackexchange. The options are:

  1. Set the capabilities on interpreter itself. This can be bad because anyone can has this privilege.
  2. Write a wrapper executable which will only execute your script, and set desired capabilities on this executable.
Related Topic