Executing ping within a snap

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?

For reference, this is my snapcraft.yml: https://github.com/orf/gping/blob/master/snapcraft.yaml

Popey in this issue (https://github.com/orf/gping/issues/41#issuecomment-319924287) says " it seems the ping executable has a sticky bit which breaks inside snap.".

A broken version showing this can be installed with snap install --edge gping --revision 9

1 Like

I tested the snap earlier and get an apparmor denial when it uses ping

[1989774.216845] audit: type=1400 audit(1501753257.314:1282): apparmor="DENIED" operation="create" profile="snap.gping.gping" pid=25611 comm="ping" family="inet" sock_type="raw" protocol=1 requested_mask="create" denied_mask="create"

@jdstrand Is this something we need an additional interface for, or a change to an existing one?

Yes, ping in the Ubuntu archive has the setuid bit set, which snapcraft correctly strips. You have a couple of options:

  1. adjust your snap to plugs ‘network-observe’ and use /bin/ping from the core snap
  2. 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.

4 Likes

Thank you! That worked great.

3 Likes

Thanks @jdstrand - works perfectly now. Nice one @orf

Just out of interest, can I detect if the network-observe plug is not connected, without trying to execute 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

Ahh I see something in the documentation.

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.

Hi all!

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?

Thanks!

so that … when installing packetsniffer.ogra you wont recognize that i’m getting sent all your web passwords ? :wink:

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.

Best,

Eloy

Hi guys,

I just tried the gping snap today and it seems like AppArmor is denying its access to /home/user.

Does it really require access to home? If yes, then we need to add the home plug.

Best,
Saad

Can you please show the denial you got? dmesg | grep DENIED can show this.

Yes, follow the process detailed in Process for aliases, auto-connections and tracks to request auto-connection.

Thank you very much Jaime for the response.

Best wishes :slight_smile:

Eloy

Thanks @jdstrand. It worked.