Closed jaraco closed 2 months ago
Note, this feature would be unnecessary for my use case if #79 were implemented by adding automatic privilege inference to the _Socket
object.
Hi @jaraco,
I would like the traceroute
function to be able to be run without privileges. However, this is not possible. I provided an answer at the time on this subject: https://github.com/ValentinBELYN/icmplib/issues/6#issuecomment-780099407
If you have a solution, I'm interested!
However, this is not possible.
I can't remember why at the time I thought that setting privileged=False
on the socket would also allow it to run unprivileged.
I went back and tried recreating my findings. I created this Dockerfile:
FROM jaraco/multipy-tox
RUN useradd -ms /bin/bash appuser
USER appuser
WORKDIR src
CMD py -m pip-run . -- -m examples.traceroute
And ran it with docker run -it -v @$(pwd):/src @$(docker build -q .)
It fails with:
icmplib.exceptions.SocketPermissionError: Root privileges are required to create the socket
Patching the project to disable privilege:
diff --git a/icmplib/traceroute.py b/icmplib/traceroute.py
index 7dd45f8..bbaed5f 100644
--- a/icmplib/traceroute.py
+++ b/icmplib/traceroute.py
@@ -167,7 +167,7 @@ def traceroute(address, count=2, interval=0.05, timeout=2, first_hop=1,
host_reached = False
hops = []
- with _Socket(source) as sock:
+ with _Socket(source, privileged=False) as sock:
while not host_reached and ttl <= max_hops:
reply = None
packets_sent = 0
Does allow the program to run, but there are no meaningful hops:
icmplib main @ docker run -it -v @$(pwd):/src @$(docker build -q .)
[<Hop 2 [1.1.1.1]>]
* Some gateways are not responding
2 1.1.1.1 17.014 ms
So it seems the reason why traceroute requires root but ping doesn't, even though the code is almost identical, is because TTL isn't honored without privilege. Is that right?
Yes you are right.
When a router decrements the TTL to 0, the packet is destroyed and the sender is informed by an ICMP Time To Live Exceeded message. The source IP address of this message is not the machine we wish to reach but the router which destroyed the packet.
If we use DGRAM
sockets (which is the case if we set the privileged
parameter to False
), we cannot capture these responses. We can only retrieve responses (therefore ICMP Echo Reply) from the target machine.
Only RAW
sockets allow this to be done, unfortunately, but requires privileges on the system.
Today, I tried to do a traceroute in user space, but got the dreaded permission error:
icmplib.exceptions.SocketPermissionError: Root privileges are required to create the socket
By setting
privileged=False
in the construction of the_Socket
, I was able to perform a traceroute without privilege. Perhaps this project would consiedr adding aprivileged
parameter to thetraceroute
function.