Daniel F
Daniel F

Reputation: 14239

How to properly assign cap_net_raw to a Python script

I have a Python script which periodically pings machines in the network by using aioping to do it.

It requires raw socket access for the ICMP messages and one way to do this is to run the script as root, which I don't want to do.

What I've resorted to is the following:

sudo setcap cap_net_raw+ep /usr/bin/python3.8
python aio_pinger.py

where among the first lines in aio_pinger.py I call the following in order to remove cap_net_raw from the binary, but let the script still have the permissions:

import os
os.system('sudo setcap cap_net_raw-ep /usr/bin/python3.8')

This works.

The issue is that in this case, even if the script is no longer run as root, it still has root access via os.system. I need to run it as a user which can't use sudo.

When using protocols like TCP or UDP for listening, I can use something like authbind to grant normal users access to privileged ports. Is something like this possible with ICMP?

Ideally I'd just issue a command like authicmp python aio_pinger.py where I do some configuration beforehand.

An additional note: python in this case is python3 from a virtual environment. I've tried to sudo setcap cap_net_raw+ep venv/p3-pinger-2022-03-01/bin/python3, but this fails with the message

Failed to set capabilities on file `venv/p3-pinger-2022-03-01/bin/python3' (Invalid argument)

The value of the capability argument is not permitted for a file. Or the file is not a regular (non-symlink) file

Is my only option to copy the python executable from /usr/bin/python3.8 into venv/p3-pinger-2022-03-01/bin/ and use setcap on that executable there, or is there some proper way of doing this?

Upvotes: 2

Views: 2746

Answers (1)

kobzar91
kobzar91

Reputation: 11

I don't know whether it still relevant, but still. No that is not an only option, in fact, that message

Failed to set capabilities on file venv/p3-pinger-2022-03-01/bin/python3' (Invalid argument)

The value of the capability argument is not permitted for a file. Or the file is not a regular (non-symlink) file

tells you that you've tried to set capabilities into the symlink (just for a case, here the brief explanation of symlink and hardlink: https://linuxhint.com/symbolic-link-linux/) of python interpreter. You should find the original python interpreter (note, not another symlink, in that case look further) that was linked. Probably, the most reliable way to find original file is execute shell command:

ls -la ./venv/p3-pinger-2022-03-01/bin/python3

You should see smth like that:

"7 Mar  9 08:31 ./venv/p3-pinger-2022-03-01/bin/python3 -> python".

The left side (before ->) indicates file as symlink, and the right side tells you on which python interpreter you are pointed as symlink (in that case it linked to interpreter in the same directory).
In that case you should set capabilities to that "./venv/p3-pinger-2022-03-01/bin/python" interpreter and it should be enough, as "./venv/p3-pinger-2022-03-01/bin/python3" is the symlink of "./venv/p3-pinger-2022-03-01/bin/python".

Upvotes: 1

Related Questions