Received: from vps5.brixit.nl (vps5.brixit.nl [192.81.221.234]) by nld3-dev1.alpinelinux.org (Postfix) with ESMTPS id DE421780D9B for <~alpine/devel@lists.alpinelinux.org>; Fri, 22 Oct 2021 16:29:51 +0000 (UTC) Received: from [127.0.0.1] (unknown [185.31.175.226]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by vps5.brixit.nl (Postfix) with ESMTPSA id 7E770616ED; Fri, 22 Oct 2021 16:29:49 +0000 (UTC) To: ~alpine/devel <~alpine/devel@lists.alpinelinux.org> Cc: Allan Garret From: Oliver Smith Subject: AppArmor Profiles for Alpine Linux Message-ID: <12b0185e-f821-4a7d-7164-fd0398db0739@postmarketos.org> Date: Fri, 22 Oct 2021 18:29:44 +0200 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Dear Alpine developers, # Foreword before I get into the topic of this mail: I know that the process towards getting the next stable Alpine version out has been started, and that this means large changes need to be avoided. I'm not trying to propose a last minute change here, it probably makes more sense to do this some time after the release has been branched. I also understand if there's more important things to do right now than to look into AppArmor, but I happened to have time to finish up my efforts with a proof of concept now so I'll share my ideas. I've researched and experimented how we could package AppArmor profiles for programs shipped in Alpine Linux (and postmarketOS, a distro based on Alpine). # Current state Right now, apparmor is in community. It provides apparmor-profiles too as subpackage, which gets generated from the apparmor tarball. But these profiles are more like examples, they are not adjusted for Alpine and contain some weird things like nvidia_modprobe. This profile and others end up in /etc/apparmor.d, so apparmor will load them on boot after enabling the openrc service (see dmesg). Another set of profiles gets written to /usr/share (meaning they are not auto-enabled). # Getting Alpine specific profiles So how do we get a good set of profiles that work on Alpine? The apparmor wiki [1] says: > Production-ready AppArmor profiles should be packaged by your distribution, either by adding a specific profile to the application package itself, or by shipping a package containing all the AppArmor profiles. I've considered both options. ## a) "Adding a specific profile to the application package" Advantages: * can be adjusted easily when upgrading the package Neutral: * little change per package necessary if we automatically generate the subpackage with abuild Disadvantages: * additional file for the profile in the aport * not so great with included files: * they are probably not in the same repository (unless we repurpose aports.git for that) * moving common patterns from profiles to include files is not as easy * dependencies on changes in include files could lead to errors, especially when backporting to stable branches ## b) "shipping a package containing all the AppArmor profiles" Advantages: * application profiles and includes in one place * less prone to breakage between profile and includes * easier to audit * allows e.g. adding CI that only makes sense in this repository with apparmor_parser * easier to get the profiles consistent * minimal change to aports.git (just one APKBUILD added) Disadvantages: * package upgrades that need adjustments in their apparmor profile need to do the adjustment in the profile package first # Proof of concept After these considerations, I thought b) made more sense and went with it for an initial implementation to show how it would work. I'm not saying that this is the perfect way to do it, I'm happy to discuss it and get my mind changed. I've created a postmarketos-apparmor-profiles.git repository [2], based on a minimal subset of the apparmor.git / profiles examples, and adjusted paths to fit Alpine. My idea is that Alpine would have a similar repository ("alpine-apparmor-profiles.git"), and we would move everything that is not postmarketOS-specific into that repository. This profiles repository contains all include-files and one profile per Alpine/pmOS package. Naming convention is that the profile has the same name as the related package (to keep the APKBUILD simple). For demonstration purposes, I've added example profiles for gnome-calculator and postmarketos-welcome-gtk3. The APKBUILD for postmarketos-apparmor-profiles [3] (again, it would be alpine-apparmor-profiles for Alpine) is pretty short with ~40 lines, plus one line per pkgname of which a profile exists. A subpackage with install_if rule is generated automatically, so the related pkgname really only needs to be listed once. A shell script included in the repository verifies in check() that the APKBUILD has the correct list of profiles (same as in the repository). Resulting logic for users is similar to what they know from shell completions and man pages, once you add "postmarketos-apparmor-profiles" it will pull in the related subpackages for the programs you have installed. # apk add postmarketos-apparmor-profiles (1/3) Installing postmarketos-apparmor-profiles (0.0.1-r0) (2/3) Installing apparmor-profile-gnome-calculator (0.0.1-r0) (3/3) Installing apparmor-profile-postmarketos-welcome-gtk3 (0.0.1-r0) Related pmaports MR: [4] # Thoughts? I'm curious what others think of this approach, if it makes sense to go with the all-profiles-in-one-package route and if the proof of concept makes sense. Auditing of the postmarketos-apparmor-profiles repository is welcome. Thanks for reading! Best, Oliver [1]: https://gitlab.com/apparmor/apparmor/-/wikis/Profiles [2]: https://gitlab.com/postmarketOS/postmarketos-apparmor-profiles [3]: https://gitlab.com/ollieparanoid/pmaports/-/blob/apparmor/main/postmarketos-apparmor-profiles/APKBUILD [4]: https://gitlab.com/postmarketOS/pmaports/-/merge_requests/2624