How can I use snap when I don't use /home/$USER?

Hi.

I’m new to snap. Trying to see if it is something worth learning. I’m on Ubuntu16.04, I have a mixture of SSD and HDD drives, and as a result, I decided to put my home directories on /data1/home/$USER, rather than /home/$USER. I have no plan to change that.

I have learned that when you have anything other than /home/$USER as your home directory, snap does not work out of the box. I have not found a solution to make it work.

I read this thread: https://bugs.launchpad.net/snapcraft/+bug/1620771 This thread did not reach a solution. I tried what was described there: “sudo dpkg-reconfigure apparmor” and add /data1/home/ to the list of home directories, delete the caches. but the issue remained.

Is there a way to support this scenario?

Thanks in advance.

These days two things need to happen:

  1. the snaps need to be able to write to your home
  2. snap-confine needs to be able to perform mounts

For ‘1’, you can use the dpkg-reconfigure method or simply drop a file into /etc/apparmor.d/tunables/home.d. Eg, create /etc/apparmor.d/tunables/home.d/my-homes:

# set to parent directory of your user's directories. Eg, if user's dir is /foo/bar/USER,
# set this to /foo/bar/
@{HOMEDIRS}+=/foo/bar/

Once you’ve done that, reload all the profiles with this:

$ sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/*

For ‘2’, with a recent stable core image, you can add apparmor rules to /var/lib/snapd/apparmor/snap-confine. Eg, create /var/lib/snapd/apparmor/snap-confine/my-homes with:

# home directories are in /foo/bar, not /home
mount options=(rw rbind) /foo/bar/ -> /tmp/snap.rootfs_*/home/,

Then reload the snap-confine policy with:

$ sudo apparmor_parser -r /etc/apparmor.d/*snap-confine*

These settings will be remembered after this. The snap-confine directory was implemented recently for NFS home and it is planned that snapd will use this to handle alternate homes too.

1 Like

@zyga-snapd, is there any reason why we are using this:

mount options=(rw rbind) /home/ -> /tmp/snap.rootfs_*/home/,

instead of:

mount options=(rw rbind) @{HOMEDIRS}/ -> /tmp/snap.rootfs_*/home/,

If not, then I suggest using the above rule so people don’t have to fiddle with the snap-confine profile (@{HOMEDIRS} evaluates to /home/ by default; see /etc/apparmor.d/tunables/home).

Thanks!

I tried the steps, but I’m still stucked…

% % cat /etc/apparmor.d/tunables/home.d/ubuntu
# This file is auto-generated. It is recommended you update it using:
# $ sudo dpkg-reconfigure apparmor
#
# The following is a space-separated list of where additional user home
# directories are stored, each must have a trailing '/'. Directories added
# here are appended to @{HOMEDIRS}.  See tunables/home for details.
@{HOMEDIRS}+=/data1/home/
% cat /var/lib/snapd/apparmor/snap-confine/my-homes 
mount options=(rw rbind) /data1/home/ -> /tmp/snap.rootfs_*/home/,
% snap remove hello
hello removed
% snap install hello
hello 2.10 from 'canonical' installed
% snap run hello
cannot create user data directory: /data1/home/hideo-t/snap/hello/20: Read-only file system

Since you mentioned “with a recent stable core image” I checked the snap version that gets installed by ubuntu 16.04. It says:

% apt-cache show snapd
Package: snapd
Architecture: amd64
Version: 2.29.4.2

Is this recent enough?

Did you reload the profiles with apparmor_parser?

Are there security denials? What is the output of sudo journalctl | grep audit at the time of the denial?

What is the output of snap version?

Yes, I did run apparmor_parser as follows:

% sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/*
% sudo apparmor_parser -r /etc/apparmor.d/*snap-confine*
% ls /var/lib/snapd/apparmor/profiles/*
/var/lib/snapd/apparmor/profiles/snap.core.hook.configure  /var/lib/snapd/apparmor/profiles/snap.hello.universe
/var/lib/snapd/apparmor/profiles/snap.hello.hello
% ls /etc/apparmor.d/*snap-confine*
/etc/apparmor.d/snap.core.3604.usr.lib.snapd.snap-confine  /etc/apparmor.d/usr.lib.snapd.snap-confine.real
/etc/apparmor.d/snap.core.3748.usr.lib.snapd.snap-confine

And sadly, I still get:

% snap run hello
cannot create user data directory: /data1/home/hideo-t/snap/hello/20: Read-only file system

And the snap version:

% snap --version
snap    2.30
snapd   2.30
series  16
ubuntu  16.04
kernel  4.10.0-42-generic

jounalctl output is as follows (no log entry around time of error):

% date
Thu Jan  4 00:18:10 JST 2018
% snap run hello
cannot create user data directory: /data1/home/hideo-t/snap/hello/20: Read-only file system
% sudo journalctl | grep audit | tail
Jan 04 00:14:57 seventeen audit[31356]: AVC apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/snapd/snap-confine//mount-namespace-capture-helper" pid=31356 comm="apparmor_parser"
Jan 04 00:14:57 seventeen audit[31356]: AVC apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/snapd/snap-confine//snap_update_ns" pid=31356 comm="apparmor_parser"
Jan 04 00:14:57 seventeen audit[31354]: AVC apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/snap/core/3604/usr/lib/snapd/snap-confine" pid=31354 comm="apparmor_parser"
Jan 04 00:14:57 seventeen kernel: audit: type=1400 audit(1514992497.339:53): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/snapd/snap-confine//mount-namespace-capture-helper" pid=31356 comm="apparmor_parser"
Jan 04 00:14:57 seventeen kernel: audit: type=1400 audit(1514992497.339:54): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/usr/lib/snapd/snap-confine//snap_update_ns" pid=31356 comm="apparmor_parser"
Jan 04 00:14:57 seventeen kernel: audit: type=1400 audit(1514992497.339:55): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/snap/core/3604/usr/lib/snapd/snap-confine" pid=31354 comm="apparmor_parser"
Jan 04 00:14:57 seventeen audit[31354]: AVC apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/snap/core/3604/usr/lib/snapd/snap-confine//mount-namespace-capture-helper" pid=31354 comm="apparmor_parser"
Jan 04 00:14:57 seventeen audit[31354]: AVC apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/snap/core/3604/usr/lib/snapd/snap-confine//snap_update_ns" pid=31354 comm="apparmor_parser"
Jan 04 00:14:57 seventeen kernel: audit: type=1400 audit(1514992497.367:56): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/snap/core/3604/usr/lib/snapd/snap-confine//mount-namespace-capture-helper" pid=31354 comm="apparmor_parser"
Jan 04 00:14:57 seventeen kernel: audit: type=1400 audit(1514992497.367:57): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="/snap/core/3604/usr/lib/snapd/snap-confine//snap_update_ns" pid=31354 comm="apparmor_parser"

Ok, there are no apparmor denials so this should indicate that snap-confine has the correct security policy. However, the “read-only” filesystem is weird. Is the filesystem mounted read-only? (this might happen if there were filesystem errors, but I suspect you would see a lot more issues than just this). Do you have other mounts that are interfering with the creation? Are the directory permissions and ownerships ok for /data1/home/hideo-t/snap/hello and /data1/home/hideo-t/snap?

Hmmm, I’m not seeing any mount issues.
Every directory under $HOME/snap is writable with my own uid.

% ls -la snap snap/hello snap/hello/20
snap:
total 12
drwxr-xr-x   3 hideo-t hideo-t 4096 Jan  3 23:35 .
drwxr-xr-x 102 hideo-t hideo-t 4096 Jan  4 09:30 ..
drwxr-xr-x   4 hideo-t hideo-t 4096 Jan  3 23:35 hello

snap/hello:
total 16
drwxr-xr-x 4 hideo-t hideo-t 4096 Jan  3 23:35 .
drwxr-xr-x 3 hideo-t hideo-t 4096 Jan  3 23:35 ..
drwxr-xr-x 2 hideo-t hideo-t 4096 Jan  3 23:35 20
drwxr-xr-x 2 hideo-t hideo-t 4096 Jan  3 23:35 common
lrwxrwxrwx 1 hideo-t hideo-t    2 Jan  3 23:35 current -> 20

snap/hello/20:
total 8
drwxr-xr-x 2 hideo-t hideo-t 4096 Jan  3 23:35 .
drwxr-xr-x 4 hideo-t hideo-t 4096 Jan  3 23:35 ..

% mount|grep 'snap\|data1'
/var/lib/snapd/snaps/core_3604.snap on /snap/core/3604 type squashfs (ro,nodev,relatime)
/var/lib/snapd/snaps/core_3748.snap on /snap/core/3748 type squashfs (ro,nodev,relatime)
/dev/sdb2 on /data1 type ext4 (rw,nosuid,nodev,relatime,data=ordered)
/var/lib/snapd/snaps/hello_20.snap on /snap/hello/20 type squashfs (ro,nodev,relatime)
tmpfs on /run/snapd/ns type tmpfs (rw,nosuid,noexec,relatime,size=3286976k,mode=755)
nsfs on /run/snapd/ns/hello.mnt type nsfs (rw)

Are there any other logs or config files I should check?

I suspect you’d need to update more than just the AppArmor rule to get snap-confine working. The C code is explicitly bind mounting /home, so it won’t see the tunable.

1 Like

If it is not an intended scenario, it’s not a bug.
Should I submit a feature request or something?

I think the reason is that snap-confine contains hard-coded logic that bind mounts /home into the execution environment. We could take the more generalized @{HOMEDIRS}/ rule but we would not automatically bind mount, for example /foo/bar.

Right, I forgot about that aspect of this and you and @jamesh are right. I did this successfully on a system, but that system happened to have a symlink from /home to /other/location, so it (accidentally) worked with my suggested changes. I think the logic that would detect if we should modify @{HOMEDIRS} would also need to flag snap-confine to mount that alternate directory.

At this point, the only course of action would be to bind mount /foo/bar on /home, as @zyga-snapd suggested elsewhere.

2 Likes

I tried the bind mount approach as suggested, and it worked fine as expected.

I’ll try out for a while to see if my existing settings don’t break too bad.

Thanks!

1 Like

Would someone be able to summarize what to do exactly? I am having the same issue, followed @jdstrand’s steps but I am still having the same problem.

@hideo67 Did you successfully fix the problem?

Thanks!

The idea suggested is to bind mount the home directory currently elsewhere under /home so that snaps can find it in the usual place.

We can eventually support other home locations, but that’s not a high priority at the moment since it’s infrequently necessary and easy to workaround with a bind mount.

Hi,

I used a bind mount, and changed /etc/passwd to relocate my home directory to its usual place.

It was easy to make snap work, the cost I had to pay was reconfigure a bunch of CMake C++ projects source directories that were inside my home directory. It took a couple of hours, but was bearable for me.

This worked for me.

snap 2.32.9+18.04
snapd 2.32.9+18.04
series 16
ubuntu 18.04
kernel 4.15.0-22-generic

App: Mattermost and onlyofficedesktopeditors

Thanks.

@hideo67 please explain clearly. Stucked with same issue. It will be helpful for me. Thanks in advance

Hi there,

I tried all this, but Snap is still telling

cannot create user data directory: /media/daten/home/robert/snap/spotify/16: Permission denied

What to do know?

 snap --version
snap    2.34.3
snapd   2.34.3
series  16
ubuntu  18.04
kernel  4.15.0-32-generic

Hi. Here is what you need to do.

Your home directory must actually be /home/$USER
You need to do whatever necessary to make your home directory located in that place.

I used to have my home directory on a place /data1/home/hideo.
I done that to use a second SSD drive with bigger free space.
I made that directory look like /home/hideo to the operating system.

Here is what I did:

Step 1. I added the following line on /etc/fstab

/data1/home /home none bind

This will cause a “bind mount”.

After a reboot, my home directory is visible in 2 locations, the original /data1/home/hideo and /home/hideo

Now, I need to actually make my home directory to be /home/hideo.

Step 2. For that, I edited /etc/passwd and searched for my entry, changed the home directory location from /data1/home/hideo to /home/hideo

Then, logout and login again. Now my home directory is /home/hideo.

And snap works.

I had a bunch of files in my home directory that contained absolute path names within that home directory.
I deleted them all and recreated them.

To conclude, as far as I know, you cannot keep your home directory at someplace other than /home/$USER. You have to actually move your home directory location to the standard place.

Hope this is clear enough.

Cheers.