Snaps and NFS /home

This came up again in IRC today, so thought I’d bring up a forum topic and my thoughts on the matter. Perhaps if we decide on a course of action, someone can implement something to make the situation better.

This is https://launchpad.net/bugs/1662552

Summary of problem:

  1. snap-confine has network security policy denials because it is trying to do things in ~/snap because ~ is on NFS
  2. snaps have security policy denials for accessing anything in ~ (eg, $SNAP_USER_COMMON, $SNAP_USER_DATA or when plugging the ‘home’ interface and trying to access those files)

The bug describes a workaround for ‘1’[1]. If people do that, ‘2’ only is a problem with snaps that don’t specify ‘network’ in their plugs.

If we want to do more than point people at the workaround, with current kernel limitations, we are pretty limited in what we can do. What we don’t want to do is simply allow networking everywhere for all users to accommodate the comparatively few NFS /home users. What we can do is detect if /home is NFS, and then unconditionally adjust snap-confine’s policy and (somehow) conditionally add policy for snaps to allow NFS (with audit logging for transparency).

The simplest way to achieve this is consider NFS /home as a global toggle. Specifically:

  1. change cmd/snap-confine/snap-confine.apparmor.in in the snapd sources to #include a file in /var/lib/snapd/somewhere that snapd will manage
  2. check if /home is NFS whenever security policy is generated/refreshed. If /home is not NFS, then generate policy as normal. Otherwise proceed to step 3
  3. update /var/lib/snapd/somewhere/home-nfs to contain rules needed for snap-confine to run with /home NFS, and reload the snap-confine policy
  4. create a HomeNFS snippet for apparmor and seccomp and if /home is on NFS, unconditionally add it to default apparmor profile and default seccomp
  5. write an INFO message to syslog that all policy is using NFS

Variations exist. Instead of runtime detection, make it a global configuration toggle. Eg, instead of ‘1’, use snap config core set home-nfs=1 that the check in ‘2’ will look at.

Considerations:

  • Of course adding the conditional NFS policy weakens the policy of snap-confine and the snaps, but with the above it is only done on systems that actually use /home NFS
  • One issue with a global toggle is that users on a system with NFS /home whose home is not on NFS get the added policy unconditionally
  • Related, there may be snaps that only the admin uses that don’t need the NFS policy but have it. It would be possible to make the NFS policy per-snap-opt-outtable rather than global.
  • Another consideration is some systems will be configured where /home is not be on NFS but users need to access other files on the system that are on NFS (in these cases, snap-confine doesn’t need NFS policy, but snaps do).

[1]Note that in more recent snapd’s, the workaround for snap-confine is quite brittle, since if the core snap is newer than the installed snapd, the profile for snap-confine from the core snap is used. This profile is on read-only media.

2 Likes

Do we know what would it take to fix the kernel part of the problem (seccomp network operations)?

I do not, but it’s more than just that. Assuming that sendmsg was fixed, we’d still need the conditional policy apparmor network rules. Assuming we had fine-grained network mediation to the point of ‘network nfs’ (note, this is not something that fine-grained network mediation phase 1 or phase 2 is meant to specifically address so I’m speaking hypothetically here), we still would only want to have those rules as conditional policy.

Only if there is something like “if file is on nfs then don’t check network stuff and instead only check the file path/inode label” could we get rid of the conditional policy. That would require a path check in sendmsg which is not something seccomp is designed to do and my guess is this sort of check in the LSMs (ie AppArmor, SELinux, Tomoyo) would not be upstreamable. For a more concrete answer, you’d need someone from the kernel team, John or Tyler to comment, but I think considering changing the kernel in this way is largely academic.

Thank you for responding. I think this is unfortunate (kernel implementation details leaning) but it is what it is. Thank you for the detailed response.

Hi! I’m in this situation: I need to access files on the system that are on NFS shares from some of my snaps, like keepassxc and vlc that have the network plug specified: can I use any workaround?

What denials are you seeing? You can paste ‘grep audit /var/log/syslog’ after trying to access the NFS shares.

OK, I’m a little bit sleep today: the snaps are not seeing the mount because it’s not in the home directory: all the snap sees is a fake root directory…if I the NFS share is mounted in my home directory, snaps with the network plug would be able to access it.

Sorry for the noise!

@zyga-snapd, between this topic and Snapd vs upstream kernel vs apparmor I’m beginning to think we want to create a .d directory for snap-confine to #include so we can drop profile snippets in it. Eg:

  1. snap-confine profile has #include </var/lib/snapd/apparmor/snap-confine.d>
  2. snapd detects NFS /home (or we use the snap config core set home-nfs idea), creates /var/lib/snapd/apparmor/snap-confine.d/home-nfs with network inet, network inet6, and reloads the snap-confine profile
  3. snapd adds network inet, network inet6, to all generated snapd apparmor policy if detects NFS /home (or we use the snap config core set home-nfs idea)
  4. snapd is forcing devmode (eg, due to lack of apparmor requirements) and create /var/li/snapd/apparmor/snap-confine.d/apparmor-forced-devmode with /usr/lib/snapd/snap-exec uxr, (for the other topic) and reloads the snap-confine profile

I think this problem is understood enough for someone to work on this.

1 Like

I agree, I think we can have a quick chat and come with some agreement on what we need to do and then just get it done.

Should the directory not be under /run somewhere? Forced devmode or not, in particular, could well be different per boot on Debian.

@mwhudson - it could be under /run, but that would complicate things because it needs to exist when the profile is loaded. The apparmor unit will start before snapd on boot and then the snap-confine profile would fail to load.

An advantage of having it under /var/lib/snapd/apparmor/snapd-confine.d is that this directory can be shared between re-execs and therefore users can more easily apply workaround policy if they need to. For example, this issue is more painful for people now because it can’t be worked around any more since the re-exec’d snapd may use a profile that is in the readonly snap. Having it in the suggested directory means user changes will be persistent.

We might want a similar concept for LDAP/AD/Kerberos/etc users: Multiple users and groups in snaps

I’ve been working on this last week and I think it’s ready for review. I implemented a simple active detection of NFS under /home/ (either fstab or mountinfo must refer to it). When one is detected we inject extra snippets into all application profiles as well as into (and this is a new thing) the profile of snap-confine itself.

The PR is at https://github.com/snapcore/snapd/pull/3958 and I asked @jdstrand for the first review.

NFS support is tagged for 2.29 and I hope it can be a part of the release.

This feature should be available in the edge channel soon. It will be a part of snapd 2.29rc2 release (note that rc1 does not contain it yet).

I have the same symptoms without using NFS. I am using pbis (used to be Likewise-open) to authenticate with a windows domain server on my linux system.

damann@software01-pc ~/workspace/SmcApi $ pycharm-professional
cannot create user data directory: /home/SENSOFT/damann/snap/pycharm-professional/46: Permission denied


******* /var/log/syslog *******
Jan 16 08:42:59 software01-pc kernel: [3605620.819201] audit: type=1400 audit(1516110179.689:578): apparmor="DENIED" operation="open" profile="/snap/core/3748/usr/lib/snapd/snap-confine" name="/home/SENSOFT/damann/" pid=11548 comm="snap-confine" requested_mask="r" denied_mask="r" fsuid=2076189394 ouid=2076189394
Jan 16 08:44:00 software01-pc kernel: [3605681.454918] audit: type=1400 audit(1516110240.317:579): apparmor="DENIED" operation="open" profile="/snap/core/3748/usr/lib/snapd/snap-confine" name="/home/SENSOFT/damann/" pid=11595 comm="snap-confine" requested_mask="r" denied_mask="r" fsuid=2076189394 ouid=2076189394

FYI solved my problem by uninstalling my snap (pycharm-professional), uninstalling snapd, and downloading the tar.gz version. Bye.

Hi, any solution for snaps while installing in NFS… Please help me with this.Thanks in advance. @jdstrand @zyga-snapd

Hey

This is interesting. The denial, dissected, says:

Jan 16 08:42:59 software01-pc kernel: [3605620.819201] audit: type=1400 audit(1516110179.689:578): apparmor="DENIED" operation="open" profile="/snap/core/3748/usr/lib/snapd/snap-confine" name="/home/SENSOFT/damann/" pid=11548 comm="snap-confine" requested_mask="r" denied_mask="r" fsuid=2076189394 ouid=2076189394

The process running under profile "/snap/core/3748/usr/lib/snapd/snap-confine (this is a profile used by internal part of snapd itself) tired to access /home/SENSOFT/damann/ for reading (request_mask="r") but reading was denied (denied_mask="r").

What is curious about this is that snap-confine doesn’t need to access one’s home directory. I wonder if any of this is caused by ALL-CAPS home directory.

I will add this to my backlog to investigate.

what the hell it s taht.
i am not expert no special user but why we can’t simplify snap modification of applications ?

i install pycharm and i get the same errors i can’t launch pycharm without using sudo ?

i heat that application realy bad one.