ICMP Echo permissions

Sun 23 August 2020 by admin

Network ping tool, one of the most widely used tool to debug network problem. It's mainly using ICMP protocol, due to specific security requirements to send/receive ICMP ECHO packets regular user is not allowed to use it. How can dealt with it on linux box ?

  • the easiest way is to add setuid bit
$ ls -l ping
-rwxr-xr-x 1 root root 44168 May  7  2014 ping
$ ./ping 8.8.8.8
ping: icmp open socket: Operation not permitted
$ sudo chmod u+s ping
$ ./ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=6.18 ms
...

easiest but less secure, something goes wrong with ping tool you can get root permissions

  • use linux capabilities to grant only select permission for ping executable, in this case it is CAP_NET_RAW
$ sudo setcap cap_net_raw+ep ping
$ getcap ping
ping = cap_net_raw+ep
$ ./ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=120 time=6.26 ms
...

you can prevent from using CAP_NET_RAW capability set before by drop all capabilites ie.

# docker run --rm -ti --cap-drop all  -u nobody -v /app:/app ubuntu:xenial bash
nobody@536ab7b0a202:/$ /app/ping 8.8.8.8
bash: /app/ping: Operation not permitted
  • use ping_group_range introduces in kernel 2.6.39 to specify group IDs to allow use ICMP Echo. In my testing env ping command doesn't use this feature, but ie. blackbox-exporter does
# sysctl net.ipv4.ping_group_range
net.ipv4.ping_group_range = 1 0
$ ./blackbox_exporter
level=info ts=2020-08-21T09:41:35.356Z caller=main.go:212 msg="Starting blackbox_exporter" version="(version=0.17.0, branch=HEAD, revision=1bc768014cf6815f7e9d694e0292e77dd10f3235)"
level=info ts=2020-08-21T09:41:35.356Z caller=main.go:213 msg="Build context" (gogo1.14.4,userroot@626fb3899f41,date20200619-11:54:41)=(MISSING)
level=info ts=2020-08-21T09:41:35.357Z caller=main.go:225 msg="Loaded config file"
level=info ts=2020-08-21T09:41:35.357Z caller=main.go:369 msg="Listening on address" address=:9115
$ curl http://127.0.0.1:9115/probe\?module\=icmp\&target\=8.8.8.8\&debug\=true
Logs for the probe:
ts=2020-08-21T09:42:04.093403654Z caller=main.go:304 module=icmp target=8.8.8.8 level=info msg="Beginning probe" probe=icmp timeout_seconds=119.5
ts=2020-08-21T09:42:04.093611876Z caller=icmp.go:84 module=icmp target=8.8.8.8 level=info msg="Resolving target address" ip_protocol=ip6
ts=2020-08-21T09:42:04.093655572Z caller=icmp.go:84 module=icmp target=8.8.8.8 level=info msg="Resolved target address" ip=8.8.8.8
ts=2020-08-21T09:42:04.0936896Z caller=main.go:119 module=icmp target=8.8.8.8 level=info msg="Creating socket"
ts=2020-08-21T09:42:04.093761517Z caller=main.go:119 module=icmp target=8.8.8.8 level=debug msg="Unable to do unprivileged listen on socket, will attempt privileged" err="socket: permission denied"
...
# sysctl "net.ipv4.ping_group_range=1 10000"
net.ipv4.ping_group_range = 1 10000
$ curl http://127.0.0.1:9115/probe\?module\=icmp\&target\=8.8.8.8\&debug\=true
Logs for the probe:
ts=2020-08-21T09:42:31.555967267Z caller=main.go:304 module=icmp target=8.8.8.8 level=info msg="Beginning probe" probe=icmp timeout_seconds=119.5
ts=2020-08-21T09:42:31.556083814Z caller=icmp.go:84 module=icmp target=8.8.8.8 level=info msg="Resolving target address" ip_protocol=ip6
ts=2020-08-21T09:42:31.556103699Z caller=icmp.go:84 module=icmp target=8.8.8.8 level=info msg="Resolved target address" ip=8.8.8.8
ts=2020-08-21T09:42:31.556116185Z caller=main.go:119 module=icmp target=8.8.8.8 level=info msg="Creating socket"
ts=2020-08-21T09:42:31.556238055Z caller=main.go:119 module=icmp target=8.8.8.8 level=info msg="Creating ICMP packet" seq=40177 id=3941
...