Arch Linux and AppArmor

apparmor
mborzecki
upcoming

#1

The post details steps needed to get snapd working on Arch Linux with AppArmor confinement enabled.

The extra/linux-hardened kernel has AppArmor enabled since 4.17.4, see https://git.archlinux.org/svntogit/packages.git/commit/trunk?h=packages/linux-hardened&id=14eccc6c604d37fa3001146f5bd4ca32ffa15c4f for details. Having installed the kernel it should be possible to use AppArmor for confining snap applications.

Installation

Getting AppArmor to work on Arch is nicely detailed in the wiki page: https://wiki.archlinux.org/index.php/AppArmor

In brief the steps are

$ pacman -Syu linux-hardened

Install apparmor from AUR. I am lazy and ended up using pacaur:

$ pacaur -S apparmor

NOTE: Should you hit a problem installing perl-rpc-xml (which is a dependency), consult the comments in the AUR page: https://aur.archlinux.org/packages/perl-rpc-xml

Lastly, enable apparmor.service, set up proper entries in your favourite bootloade and make sure to add apparmor=1 security=apparmor to the kernel command line.

snapd

Once AppArmor is enabled, snapd will detect that and generate proper profiles for each installed snap. One still needs to:

  • rebuild snap-confine with AppArmor support
  • update snapd to not downgrade the confinement in generated profiles (since we have a recent enough kernel)

Apply the following diff to PKGBUILD to enable AppArmor support in snap-confine:

diff --git a/PKGBUILD b/PKGBUILD
index 57ecfe3..3d9ca6e 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -72,7 +72,7 @@ build() {
     --prefix=/usr \
     --libexecdir=/usr/lib/snapd \
     --with-snap-mount-dir=/var/lib/snapd/snap \
-    --disable-apparmor \
+    --enable-apparmor \
     --enable-nvidia-biarch \
     --enable-merged-usr
   make $MAKEFLAGS

Also grab the patch for snapd from here and add it to PKGBUILD:

Once the pull-request lands in master, it will be possible to rebuild snapd-git package with a simple change to pass --enable-apparmor in PKGBUILD, no extra patches needed.

Once snapd is started, check if apparmor was correctly detected:

$ snap debug sandbox-features
apparmor:             kernel:caps kernel:domain kernel:file kernel:mount kernel:namespaces kernel:network_v8 kernel:policy kernel:ptrace kernel:query kernel:rlimit kernel:signal
confinement-options:  classic devmode
dbus:                 mediated-bus-access
kmod:                 mediated-modprobe
mount:                freezer-cgroup-v1 layouts-beta mount-namespace per-snap-persistency per-snap-profiles per-snap-updates per-snap-user-profiles stale-base-invalidation
seccomp:              bpf-argument-filtering kernel:allow kernel:errno kernel:kill_process kernel:kill_thread kernel:log kernel:trace kernel:trap
udev:                 device-cgroup-v1 tagging

snaps

$ snap install hello-world
$ snap list
maciek@corsair:arch/aur/snapd (git)-[master] snap list
Name         Version    Rev   Tracking  Publisher   Notes
core         16-2.34.3  5145  stable    canonical?  core
hello-world  6.3        27    stable    canonical?  -

Double check that profiles were generated:

$ ls /var/lib/snapd/apparmor/profiles/snap.hello-world.*
/var/lib/snapd/apparmor/profiles/snap.hello-world.env
/var/lib/snapd/apparmor/profiles/snap.hello-world.evil
/var/lib/snapd/apparmor/profiles/snap.hello-world.hello-world
/var/lib/snapd/apparmor/profiles/snap.hello-world.sh

Verify that snap-confine profile exists at /etc/apparmor.d/usr.lib.snapd.snap-confine

And that snap-confine and snap profiles were loaded by AppArmor:

$ sudo apparmor_status
92 profiles are loaded.
89 profiles are in enforce mode.
   ...
   /usr/lib/snapd/snap-confine
   /usr/lib/snapd/snap-confine//mount-namespace-capture-helper
   snap-update-ns.core
   snap-update-ns.hello-world
   snap.core.hook.configure
   snap.hello-world.env
   snap.hello-world.evil
   snap.hello-world.hello-world
   snap.hello-world.sh
   ...
2 processes have profiles defined.
...

At this point hello-world.evil should be correctly blocked:

$ hello-world.evil                            
Hello Evil World!
This example demonstrates the app confinement
You should see a permission denied error next
/snap/hello-world/27/bin/evil: 9: /snap/hello-world/27/bin/evil: cannot create /var/tmp/myevil.txt: Permission denied

And you should see a denial in dmesg like this:

[ 7937.185833] audit: type=1400 audit(1535115949.343:578): apparmor="DENIED" 
    operation="open" profile="snap.hello-world.evil"
    name="/var/tmp/myevil.txt" 
    pid=17653 comm="evil" requested_mask="wc" denied_mask="wc" 
    fsuid=1000 ouid=1000

The non-evil hello-world should still work:

$ hello-world
Hello World!

#2

How AppArmor functionality in snapd is affected by lack of Ubuntu AppArmor patches in upstream kernels?


#3

@jdstrand is probably the best person to answer this. It is my understanding that most of support is already in the mainline since 4.16+. We’ve had openSUSE Tumbleweed with 4.16 and up kernels using the default template for some time now.


#4

There is no fine grained mediation of UNIX sockets so by extension there is no DBus method mediation. I believe some other things are missing but having some confinement is better than not having it as long as we are clear about this fact (snap debug confinement and snap debug sandbox-features)


#5

@zyga is right that unix and dbus are missing, but for network mediation you also need a compatible apparmor userspace that isn’t available yet (ie, the upcoming 3.0).

While I agree in the general idea that some confinement is better than none, we need to be careful because users may make decisions based on the confinement level of the system. Ie, we don’t want to be in a position where someone thinks their system supports full strict confinement when it doesn’t. Lack of unix, dbus and network rules represent significant gaps in the confinement story, and while we are on the right path towards everything being upstream, we need to be honest we aren’t there yet.


#6

Thx, for the replies.

One more question: what happens when I boot kernel with different level of apparmor support (or no support at all) after installing snap?

Is snap capable of detecting apparmor support at runtime and rise/decrease sandboxing level accordingly?


#7

The snapd daemon tracks which apparmor features are available when it starts and updates security profiles each time there is a change.

Make sure to have apparmor userspace tooling (apparmor_parser) present when you boot a kernel with apparmor enabled (i.e. apparmor=1 security=apparmor) and /sys/kernel/security/apparmor is mounted. Otherwise snapd assumes that apparmor is functional and tries to load/unload profiles when installing/removing snaps.


#8

I have enabled AppArmor in snapd-git now, meaning apparmor is now a dependency. Once https://github.com/snapcore/snapd/pull/5894 lands, the profiles will not be downgraded anymore. I’m also working with @cachio to get the out test suite use Arch image with AppArmor enabled. Once that’s done, I’ll enable AppArmor in snapd AUR package with 2.36 release.


#9

Great job! Thank you.