5

While running a rootless Ubuntu image with podman on a Fedora host, ping fails with an "Operation not permitted" error.

root@337e8ebdc287:/# ping google.com
bash: /usr/bin/ping: Operation not permitted

On alpine/fedora images, ping works

$ podman run alpine ping -c1 google.com
PING google.com (172.217.169.110): 56 data bytes
64 bytes from 172.217.169.110: seq=0 ttl=42 time=119.706 ms

--- google.com ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 119.706/119.706/119.706 ms

It works on Ubuntu too when I run the image with --privileged.

On host, ping_group_range is set to include all uids.

$ sudo sysctl --all | grep ping
net.ipv4.ping_group_range = 0   2147483647

Using Fedora 36 with Podman 4.2.1.

How do I make ping work on rootless Ubuntu image?

Aside from the answer to this specific question, I'm interested in learning to debug this kind of permission issue myself. Do I have to know beforehand every possibility that leads to the "Operation not permitted" error? Is this error thrown by the OS or the program that's being run? If it's thrown by the OS, does it also log somewhere why it didn't permit the operation?

epokhe
  • 151

1 Answers1

8

As you certainly know, containers make use of certain kernel features. Most prominently this includes kernel namespaces and resource groups.

To interact with the network, you usually interact with the kernel through syscals. When you try executing syscalls, the kernel checks whether you have permission to perform these syscalls. This check considers which user you currently use (calling user), which user executes the program (executing user) and which capabilities are granted in the execution context.

As you can see in this GitHub issue (https://github.com/mviereck/dockerfile-x11docker-deepin/issues/19), ping requires the NET_RAW capability. Check https://security.stackexchange.com/a/128988 as to what this means. You might also want to read https://superuser.com/a/1702188/1737591 on a similar question. This also helps explain why it works as expected with alpine but not with the ubuntu image.

With the --privileged Flag, you basically have a shorthand for including this CAP_NET_RAW among many other permissions. You should instead be able to execute the container with the --cap-add=NET_RAW flag in order to limit the capabilities to a minimum.

I do not know where these errors might get logged but I'd check dmesg and the system's syslogs first.

EDIT:

When using the official ubuntu image and installeing ping on it afterwards, you also need to run setcap cap_net_raw+p /usr/bin/ping inside said container. Otherwise the permission check within the container itself (defining the execution context) will not allow you to execute ping as the required capability will not be part of the effective capabilities.

$ podman run --rm -it ubuntu:22.04
Resolved "ubuntu" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/ubuntu:22.04...
Getting image source signatures
Copying blob cf92e523b49e skipped: already exists  
Copying config 216c552ea5 done  
Writing manifest to image destination
Storing signatures
root@af1a4b5052e9:/# apt-get update && apt-get install -y iputils-ping && apt-get clean autoclean && apt-get -y autoremove
### Skipped apt output ###
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
root@af1a4b5052e9:/# ping -c 3 stackoverflow.com
bash: /usr/bin/ping: Operation not permitted
root@30d9c3c936fc:/# sysctl 'net.ipv4.ping_group_range'             
net.ipv4.ping_group_range = 0   0
root@af1a4b5052e9:/# setcap cap_net_raw+p /usr/bin/ping
root@af1a4b5052e9:/# ping -c 3 stackoverflow.com
PING stackoverflow.com (151.101.193.69) 56(84) bytes of data.
64 bytes from 151.101.193.69 (151.101.193.69): icmp_seq=1 ttl=255 time=8.61 ms
64 bytes from 151.101.193.69 (151.101.193.69): icmp_seq=2 ttl=255 time=8.67 ms
64 bytes from 151.101.193.69 (151.101.193.69): icmp_seq=3 ttl=255 time=8.86 ms

--- stackoverflow.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 8.609/8.713/8.857/0.105 ms root@af1a4b5052e9:/#

It is quite likely, that the other images you tried either include the right net.ipv4.ping_group_range already or have executed something like setcap cap_net_raw+p /usr/bin/ping before publishing the image.

Feel free to use getcap $(which ping) to list the capabilities other images might have set on ping.

cap_net_raw+ep means:
For the capability net_raw add (+) effective (e) and permitted (p).

I suggest having a look at https://book.hacktricks.xyz/linux-hardening/privilege-escalation/linux-capabilities for a primer regarding capabilities if you are eager to learn more.