How to snap an apt transport?

Hello!

We have this pet project that is an apt transport for IPFS. It’s now working nicely, so I want to package it as a snap.

However, to install a transport one has to copy the file to /usr/lib/apt/methods/. Is there an alternative way to do this that works for snaps?

pura vida

I don’t believe that we have an interface for writing to that directory specifically, but even if you could, /usr/lib/apt/methods for a strictly confined snap is not the same as what’s on the host filesystem, you would need to modify /var/lib/snapd/hostfs/usr/lib/apt/methods to get at the host.

However, you could theoretically use system-files to access /var/lib/snapd/hostfs/usr/lib/apt/methods, but this is likely not the intention of the system-files interface.

Perhaps @jamesh could comment on this use case, I know there is ongoing work to support installing packages on the host from a strictly confined snap and this sounds like a similar type of thing.

Otherwise, you could always try requesting classic confinement which turns off all snap confinement and would allow you to write to /usr/lib/apt/methods (which would also be the same as the host, unlike with strict confinement).

1 Like

The interfaces I’ve been working on wouldn’t really help here: granting access to apt via packagekitd is not quite the same as letting a confined app blat files all over the host file system.

The system-files solution would probably work. Whether it passes @jdstrand’s manual review is another question.

For reference, this is what that solution would look like:

  1. add a plug definition to the snap, something like this:

    plugs:
      apt-method:
        interface: system-files
        write:
          - /var/lib/snapd/hostfs/usr/lib/apt/methods/ipfs
    
  2. add configure and remove hooks to the snap, both with the apt-method plug attached. In the congfigure hook, symlink /snap/bin/${SNAP_INSTANCE_NAME}.app to /var/lib/snapd/hostfs/usr/lib/apt/methods/ipfs. In the remove hook, remove the symlink.

  3. for added robustness, have each hook fail if the .../apt/methods/ipfs path exists but is not a symlink to the expected target.

By attaching the plug to the hooks, none of the apps within the snap should have write access to the .../apt/methods directory. This is more for protection against the snap malfunctioning than security: if your snap is granted access to this plug, an update that applied the plug to apps within the snap would still pass review.

1 Like

This could probably be more robust if it they were interface connect/disconnect hooks, then an end-user disconnecting this hook would be able to deny the snap access to that specific apt method.

Also, in the host mount namespace, a symlink to /var/lib/snapd/hostfs/usr/lib/apt/methods/ipfs wouldn’t work because /var/lib/snapd/hostfs only has the host namespace mounted there inside a snap. It would be fine to do a symlink to /snap/$SNAP_NAME/current/usr/lib/apt/methods/ipfs which works both inside and outside snaps.

1 Like

I should have said "symlink to /snap/bin/${SNAP_INSTANCE_NAME}.whatever". It definitely shouldn’t symlink through to /snap/$SNAP_NAME/current/usr/lib/apt/methods/ipfs, since that means the transport will be called without confinement: bad from both a security standpoint and library compatibility standpoint.

A dedicated interface could avoid this kind of thing, but someone would need to write it and someone would need to review it.

1 Like

Ah right I didn’t realize that the apt transport wasn’t just a data file, yes if it’s an executable then /snap/bin/$SNAP_NAME.app is the right thing to do.

1 Like