I’m having some issues executing ping within a snap. For context, I have a program called gping that executes ping and produces a console graph of it.
I’ve managed to bundle it inside a snap, but executing ping errors with “icmp open socket: Permission denied”. Has anyone got any idea of how to work around this?
Yes, ping in the Ubuntu archive has the setuid bit set, which snapcraft correctly strips. You have a couple of options:
adjust your snap to plugs ‘network-observe’ and use /bin/ping from the core snap
adjust the ping in your snap to not require setuid. ping is currently setuid because it needs CAP_NET_RAW because it uses SOCK_RAW packets. Perhaps your program can invoke ping with different options.
I might mention that the kernel now supports the net.ipv4.ping_group_range sysctl which with a modern version of ping, the kernel will allow ping to use SOCK_DGRAM packets (without root, etc). This isn’t well integrated in Ubuntu or the core snap though. See https://bugs.launchpad.net/ubuntu/+source/iputils/+bug/1588917
Thank you for the response! I’m interested in option 1, can you elaborate on how I can use /bin/ping from the core snap? I’m fairly new to building snaps, any documentation links or anything to point me in the right direction would be very helpful.
Stop staging iputils-ping in your snapcraft.yaml so you don’t ship ping yourself, plugs network-observe, make sure the interface is connected (sudo snap connect gping:network-observe) and call ‘ping’ like you would any other command. If you need to stage-package iputils-ping for other reasons, you can call /bin/ping directly or adjust your PATH in the snap so /bin/ping is found before your ping.
You can add an interface hook so that you get notified (e.g. you can tweak a config file or something alike) when an interface is connected/disconnected. CC @pstolowski can elaborate on this
Just a FYI, something like a simple environment variable would cover a lot of use cases. If my snap needs a plug it’s a lot simpler to just error if that environment variable is not present or set to a value and display a message.
With a hook system it seems I have to maintain some implicit state in a file somewhere, and hope that the hooks are fired and handled correctly. I get that for some situations like updating config files this is preferable, but for the general ‘output a message and quit if this plug is not connected’ use case it’s pretty heavyweight.
A simple environment variable would not work because … well, it cannot be reliably changed once a process is up and running. There is one more mechanism that is being improved (snapctl) where snaps can just ask snapd about what they need but it is not yet deployed for this purpose.
Is there any way to use network-observe interface transparently or the user
always have to execute sudo snap connect gping:network-observefrom the
command line in order to work properly? Shouldn’t those kind of interfaces
work out of the box without the user intervention?
so that … when installing packetsniffer.ogra you wont recognize that i’m getting sent all your web passwords ?
the harmless interfaces do all autoconnect, as soon as an interface could steal your data (which network-observe can surely do), we expect the user to decide … in desktop installs there is a UI for this being developed, on the commandline you will have to use “snap connect …”
This is a good point, but I think you are missing the main use case: display an error message and quit if the plug is not connected. For that an environment variable is the perfect solution.
To be honest I also don’t want to tie my programs to snapd/snapctl in that way. Please expose this in a standard way, via environment variables or maybe some kind of virtual file on the file system.
@Oliver Grawert, I see the point here… you are right.
It is good to hear that some UI is in development for all the snaps which
are oriented to the desktop. If we want snap packages are easy to use, it
would be very important to simplify their execution for all kind of users.