Home access as root from confined snaps

I’m currently at the Snapcraft Summit cooking up a snap for Plex Media Server (I’m a Plex employee, so this can become an official snap). So far, it looks promising, we can run Plex in a confined snap and even the armhf builds work on Rasperry PI :tada:

One issue we did run into is the following: in non-snap builds of Plex Media Server we are able to browse user home directories to add media. In this snap however, we can’t, as it’s a service running as root and AppArmor prevents that. I’m 99% sure that we only need read-only access.

@jdstrand helped getting a POC with an apparmor rule: @{HOME}/{,**} r,. We added this to the AppArmor profile for the snap and it seems to work. Ideally, a “homes” or similar plug could implement this rule for snaps.

Any thoughts?

2 Likes

Thanks for the topic @tamas!

Like @tamas said, we discussed this a bit. The plex server can run in a couple of ways: either as a daemon or via a session service that is started via the ~/.autostart. ~/.autostart is being discussed here: How to autostart a snap of a desktop application? so we don’t have to talk about that here. Note that plex could take the opinion that it should be a session service, and therefore be started via https://github.com/snapcore/snapd/pull/2592, but that isn’t something they do now. With both of the latter options, the ‘home’ interface works fine because the server is running as the user.

A current use case for the Plex deb is to run the service as root, and slurp up files from all the user’s home directories for playback. Plex needs only read-only to these files. Since the service runs as root, the ‘home’ interface necessarily uses ‘owner’ match and ‘owner’ matching is not fine-grained (it either matches or it doesn’t), we need to think of how we want to expose that.

In the past we’ve considered added interface attributes to the home interface in order expand it, and as a strawman I’d like to propose we use a an attribute for Plex’s use case. Using an interface attribute allows us to use snap declarations to regulate its use. I suggest:

plugs:
  home:
    allow-other-read: true

‘allow-other-read’ is inspired by DAC permissions for ‘user’, ‘group’, and ‘other’. Rather than the quick rule @tamas referenced, we instead add a series of rules that allows non-owner reads for non-hidden files except ~/snap.

Thoughts?

1 Like

I think that additional logic is trying to introduce further logic to increase safety in a case that is already unsafe regardless. If the snap has access to the home interface, and we allow snaps to .autostart as the user, the snap in effect has access to the home of anyone that logs in. Or am I missing something in this picture?

The snap has access to the home interface, yes, but because the daemon runs as root ‘owner’ match fails for anything outside of /root. Having the root daemon access files in /home has an advantage that current plex deb users utilize today: the server can access all of the users’ media, not just the media for a single user. I was trying to address that part specifically in my strawman.

Autostart is a different case and it is something we’ve not fully explored and you bring up an interesting point. Yes, if the snap plugged home and we had some mechanism for the snap to start in the user’s session, that would allow the server to access files in the login sessions where it was started (which would mean the server could copy those off somewhere). However, I always hoped that the user would have a choice in the matter of autostart, similar to what we are doing with xdg-settings for default browser-- ie, for each user that runs the snap, the user is prompted if autostart is ok. On a multiuser system, maybe only two people use the snap, but 5 don’t-- only the two that use the snap could have their data shuffled off.

The home interface has always meant your /home, so maybe your point is an argument to not use an attribute and to create a ‘home-other-observe’ manually connected interface (or maybe introduce a ‘backup’ interface, but plex requesting ‘backup’ for its use sounds like a kludge)? We could consider redefining that ‘home’ is ‘all homes’ I suppose and rely solely on traditional permissions. I think we want to be very careful here though (not to mention, the strawman is for read-only access, not read/write).

1 Like

On platforms where tray icons are … not frowned upon (cough gnome3 cough) we have a try icon where the user can check the option to autostart Plex. So ideally this is something that we would like the user to be able to control (tray icon or not).

Yes, that will be covered by How to autostart a snap of a desktop application? I think.

@niemeyer, I know you’ve thought about the home interface a great deal-- what do you think of this idea?

Ping @niemeyer - I’m doing a batch of policy updates and could include this with them if we agree on an approach.

@jdstrand Having the setting sounds fine. If nothing else, it’s no worse than having the access by default, and it does protect against security issues when the software is abused (vs. intended snap abuse).

The suggested name sounds a bit obscure, though. How about:

plugs:
    home:
        read: [ own / all ]

This will expand nicely for groups, and for writes, if we ever want to.

1 Like

FYI, I started on this and will have something up for review early next week (ie, this should be in 2.33).

FYI https://github.com/snapcore/snapd/pull/5016

1 Like

Thanks @jdstrand!

We’ve agreed to not introduce “read: own/owner”, since that’s already the default. We’ll just support the “read: all” variant.

1 Like

FYI, https://github.com/snapcore/snapd/pull/5016 is now committed and it should be in 2.33.

Hi everyone, I’m very interested as the topic title is exactly what I want.

I just installed nextcloud (nextcloud 13.0.5snap1 from ‘nextcloud’) to my server using snap (2.34.3).

My / partition is only 20GB but /home is 1TB. So I want the nextcloud data folder to be on my /home partition. I tried to symlink it, to mount it in /media as it looks it’s the only place snap can access using snap connect nextcloud:removable-media. Nothing works nextcloud looks like it’s not able to access it.

So how can I store my file in /home and access it from snap?

To answer your specific question, the nextcloud snap would need to be adjusted to use the home interface with the new interface attribute that allows non-owner reads, which it currently doesn’t do. However, even if it did, nextcloud wouldn’t work in the way you want because nextcloud would need write access.

Since your system is not setup in a manner that is compatible with the snap’s expectations, you will need to be a little creative. One thing you could try is (untested):

$ sudo snap stop nextcloud
$ sudo mkdir -p /home/nextcloud-data/snap/nextcloud/common
$ sudo mv /var/snap/nextcloud/common/nextcloud /home/nextcloud-data/snap/nextcloud/common
$ sudo ln -s /home/nextcloud-data/snap/nextcloud/common/nextcloud /var/snap/nextcloud/common/nextcloud
$ sudo snap start nextcloud

This should work because nextcloud is running as root and you are creating a directory in /home that is both owned by root and follows the pattern of the apparmor rule that will allow it to match the allow rules. If you are at some halfway point (ie, you tried something along the lines of the above) and still having problems, then make sure everything in the /home/nextcloud-data (or whatever you named it) is owned by root (eg, run sudo chown -R root:root /home/nextcloud-data).

Good luck!

Thank you! This is probably not the place to debug my problem, if I should move elsewhere please tell me.

I did what you suggested but I’m in the same state than with the symlink of the data folder approach: the screen fail to load at the end of the installation and the page is constantly refresh every 5 sec: https://screenshots.firefox.com/UUREWemxilvOxVPg/c.duparay.fr

Are there any security denials in journalctl at the time of the failed access?

If not, I’m not familiar with the internals of nextcloud but would guess that it is perhaps confused by the new paths. One way forward might be to save your data somewhere safe (removing the symlink from /var/snap/nextcloud/common that you added is probably enough, but if this is your only copy, do whatever backups will make you feel confident in the next step :wink: ) uninstall nextcloud, install nextcloud, add the symlink, and then import you data into nextcloud anew.