AppArmor in PureOS


#1

I read the blog post here about AppArmor:

https://puri.sm/posts/pureos-apparmor-activated-by-default/

I have 2 questions:

  1. Do I need to do anything to take advantage of this feature? Or will a simple sudo > update, sudo > upgrade, sudo > full upgrade do?

  2. I just recently downloaded the PureOS iso from here: https://pureos.net/download.html. The only version I can see to download is the PureOS 8.0 ‘Prometheus’ Beta. There’s no version notes or anything. How do I find out if this is the version (which I’m presuming is the latest and greatest) is the same that’s on my Librem 13 v2?

Cheers in advance.


#2

Yes.

Doesn’t matter, just sudo apt update && sudo apt full-upgrade and you’ll be at the latest version. PureOS is a rolling-release distro.


#3

Thankyou! (pad out 20 char limit)


#4

To make AppArmor protect your system there must be an active profile for each program file (application).

I have just installed PureOS 8.0 and checked the AppArmor status with

sudo aa-status

The apparmor module and 25 profiles are loaded in enforce mode (not only audit or complain mode to observe the access patterns of the applications).

In my case applications like envice, telepathy, cups, libreoffice and thunderbird are protected
but e. g. the Purebrowser seems not to be protected (no active profile) which is IMHO a big gap to be closed
since it accesses the internet.

Does anybody have a working aa profile and is willing to contribute it here or to PureOS?


#5

@mladen Reviving this thread because I think @tovadiratum makes a great point. I also just checked my AppArmor status and saw no profile present for Purebrowser. Does anyone at Purism have a functional AA profile for PureBrowser they could provide to users?


#6

As others I have stumbled upon this issue. Despite the news from Dec. 17 “PureOS now features AppArmor activated by default”, it looks as if there is no profile for Purebrowser. First thought ‘disappointing’, since so essential? Therefore I like to repeat the above question: Does anyone at Purism have a functional AA profile for Purebrowser they could provide to users? Or if available elsewhere, your hint will be appreciated. Kind regards,


#7

I don’t think any of the distros have an AppArmor profile for Firefox enabled by default. Once it’s enabled, it causes a ton of usability issues, usually related to plugins to and downloading/uploading files from non-standard locations. Maybe it’s a little better now that Firefox reduced the functionality of the plugins, but you should probably still be comfortable debugging AppArmor profiles if you are going to enable it.


#8

I can’t comment on AA profiles as I’ve never seen them prebuilt. Perhaps I will learn something new today. But here’s a write up on Medium that documents generating profiles for oneself: https://medium.com/information-and-technology/so-what-is-apparmor-64d7ae211ed

I’m sure everyone here knows how but in case there are other readers who don’t want to wait for this question to be formally resolved by Purism. There it is.


#9

There are profiles out there for Firefox, which would have to be adapted for PureBrowser, but I discovered it depends on what gets used in the browser.

I tried modifying one for PureBrowser, and later Firefox, about a year ago. I finally threw up my hands; I just did not know enough about apparmor or Firefox to feel confident anything I did would work properly. When test driving, I got warnings all the time and was never sure what to allow and what to prohibit to make the browser behave the way I wanted it to.

Both browsers have tentacles throughout the system. The sticking point for me is giving unrestricted access to the file system. Presumably, that is for things like File->Open File, which I rarely, if ever, use. I want that very limited, but others might not.


#10

I don’t use PureOS, but firejail might be what y’all need. I’ve used it in every distro I’ve ever run.


#11

I’m not on PureOS either, on Arch Linux but I’ve adapted some AppArmor profiles for firefox and chromium, I can share them here… hopefully not breaking any rules.

They may have to be modified a bit to work on your distribution, you just need to be familiar with the file system and be able to read the profile a bit. If it is not working you can set the profile to complain

    # aa-complain <profile>

Then when you run the application it will run without the AppArmor protection and any permissions that are missing or errors that are created will show up in your audit log at /var/log/audit/

You just check the log and append the appropriate permissions to the profile in order to fix whatever was missing. I pulled a profile for firefox from Ubuntu, modified it to run on Arch Linux, and added some permissions to allow U2F functionality.

The profile is here:

# vim:syntax=apparmor
# Author: Jamie Strandboge <jamie@canonical.com>

# Declare an apparmor variable to help with overrides
@{MOZ_LIBDIR}=/usr/lib/firefox

#include <tunables/global>

# We want to confine the binaries that match:
#  /usr/lib/firefox/firefox
#  /usr/lib/firefox/firefox
# but not:
#  /usr/lib/firefox/firefox.sh
/usr/lib/firefox/firefox {
  #include <abstractions/audio>
  #include <abstractions/cups-client>
  #include <abstractions/dbus-strict>
  #include <abstractions/dbus-session-strict>
  #include <abstractions/dconf>
  #include <abstractions/gnome>
  #include <abstractions/ibus>
  #include <abstractions/nameservice>
  #include <abstractions/openssl>
  #include <abstractions/p11-kit>
  #include <abstractions/ubuntu-unity7-base>
  #include <abstractions/ubuntu-unity7-launcher>

  #include <abstractions/dbus-accessibility-strict>
  dbus (send)
       bus=session
       peer=(name=org.a11y.Bus),
  dbus (receive)
       bus=session
       interface=org.a11y.atspi**,
  dbus (receive, send)
       bus=accessibility,

  # for networking
  network inet stream,
  network inet6 stream,
  @{PROC}/[0-9]*/net/arp r,
  @{PROC}/[0-9]*/net/if_inet6 r,
  @{PROC}/[0-9]*/net/ipv6_route r,
  @{PROC}/[0-9]*/net/dev r,
  @{PROC}/[0-9]*/net/wireless r,
  
  ## Different location on Arch
  #dbus (send)
  #     bus=system
  #     path=/org/freedesktop/NetworkManager
  #     member=state,
  #dbus (receive)
  #     bus=system
  #     path=/org/freedesktop/NetworkManager,

  # should maybe be in abstractions
  /etc/ r,
  /etc/mime.types r,
  /etc/mailcap r,
  /etc/xdg/*buntu/applications/defaults.list    r, # for all derivatives
  #/etc/xfce4/defaults.list r,
  /usr/share/xubuntu/applications/defaults.list r,
  owner @{HOME}/.local/share/applications/defaults.list r,
  owner @{HOME}/.local/share/applications/mimeapps.list r,
  owner @{HOME}/.local/share/applications/mimeinfo.cache r,
  
  ## Not present
  #/var/lib/snapd/desktop/applications/mimeinfo.cache r,
  #/var/lib/snapd/desktop/applications/*.desktop r,
  
  owner /tmp/** m,
  owner /var/tmp/** m,
  owner /{,var/}run/shm/shmfd-* rw,
  owner /{dev,run}/shm/org.{chromium,mozilla}.* rwk,
  /tmp/.X[0-9]*-lock r,
  /etc/udev/udev.conf r,
  # Doesn't seem to be required, but noisy. Maybe allow 'r' for 'b*' if needed.
  # Possibly move to an abstraction if anything else needs it.
  # let the shell know we launched something
  dbus (send)
     bus=session
     interface=org.gtk.gio.DesktopAppInfo
     member=Launched,

  /etc/localtime r,
  /etc/ca-certificates/trust-source/ r,
  /etc/ca-certificates/trust-source/anchors/ r,
  /etc/ca-certificates/trust-source/blacklist/ r,
  
  ## Not present
  #/etc/wildmidi/wildmidi.cfg r,

  ## firefox specific if present
  #/etc/firefox*/ r,
  #/etc/firefox*/** r,
  #/etc/xul-ext/** r,
  #/etc/xulrunner-2.0*/ r,
  #/etc/xulrunner-2.0*/** r,
  #/etc/gre.d/ r,
  #/etc/gre.d/* r,

  # noisy
  deny @{MOZ_LIBDIR}/** w,
  deny /usr/lib/firefox-addons/** w,
  deny /usr/lib/xulrunner-addons/** w,
  deny /usr/lib/xulrunner-*/components/*.tmp w,
  deny /.suspended r,
  deny /boot/initrd.img* r,
  deny /boot/vmlinuz* r,
  deny /var/cache/fontconfig/ w,
  deny @{HOME}/.local/share/recently-used.xbel r,

  # TODO: investigate
  deny /usr/bin/gconftool-2 x,

  # These are needed when a new user starts firefox and firefox.sh is used
  @{MOZ_LIBDIR}/** ixr,
  /usr/bin/basename ixr,
  /usr/bin/dirname ixr,
  /usr/bin/pwd ixr,
  /sbin/killall5 ixr,
  /bin/which ixr,
  /usr/bin/tr ixr,
  @{PROC}/ r,
  @{PROC}/[0-9]*/cmdline r,
  @{PROC}/[0-9]*/mountinfo r,
  @{PROC}/[0-9]*/stat r,
  owner @{PROC}/[0-9]*/task/[0-9]*/stat r,
  @{PROC}/[0-9]*/status r,
  @{PROC}/filesystems r,
  @{PROC}/sys/vm/overcommit_memory r,
  /sys/devices/pci[0-9]*/**/uevent r,
  /sys/devices/platform/**/uevent r,
  /sys/devices/pci*/**/{busnum,idVendor,idProduct} r,
  /sys/devices/pci*/**/{,subsystem_}device r,
  /sys/devices/pci*/**/{,subsystem_}vendor r,
  /sys/devices/system/node/node[0-9]*/meminfo r,
  
  ## Yubikey U2F
  /sys/bus/ r,
  /sys/class/ r,
  /sys/class/hidraw/ r,
  /sys/class/hidraw/hidraw? r,
  /dev/hidraw? rw,
  /run/udev/data/c240:? r,
  
  owner @{HOME}/.cache/thumbnails/** rw,

  /etc/mtab r,
  /etc/fstab r,

  # Needed for the crash reporter
  owner @{PROC}/[0-9]*/environ r,
  owner @{PROC}/[0-9]*/auxv r,
  #/etc/lsb-release r,
  /usr/bin/expr ix,
  /sys/devices/system/cpu/ r,
  /sys/devices/system/cpu/** r,
  /sys/devices/platform/ff5500000dwc3/xhci-hcd.0.auto/usb*/**/hidraw* r,

  # about:memory
  owner @{PROC}/[0-9]*/statm r,
  owner @{PROC}/[0-9]*/smaps r,

  # Needed for container to work in xul builds
  #/usr/lib/xulrunner-*/plugin-container ixr,

  # allow access to documentation and other files the user may want to look
  # at in /usr and /opt
  /usr/ r,
  /usr/** r,
  /usr/share/fonts/util/.uuid.TMP-* r,
  /usr/share/fonts/encodings/large/.uuid.TMP-* r,
  #/opt/ r,
  #/opt/** r,

  # so browsing directories works
  #/ r,
  #/**/ r,

  # Default profile allows downloads to ~/Downloads and uploads from ~/Public
  owner @{HOME}/ r,
  owner @{HOME}/Public/ r,
  owner @{HOME}/Public/* r,
  owner @{HOME}/Downloads/ r,
  owner @{HOME}/Downloads/* rw,

  # per-user firefox configuration
  owner @{HOME}/.{firefox,mozilla}/ rw,
  owner @{HOME}/.{firefox,mozilla}/** rw,
  owner @{HOME}/.{firefox,mozilla}/**/*.{db,parentlock,sqlite}* k,
  owner @{HOME}/.{firefox,mozilla}/plugins/** rm,
  owner @{HOME}/.{firefox,mozilla}/**/plugins/** rm,
  owner @{HOME}/.gnome2/firefox* rwk,
  owner @{HOME}/.cache/mozilla/{,firefox/} rw,
  owner @{HOME}/.cache/mozilla/firefox/** rw,
  owner @{HOME}/.cache/mozilla/firefox/**/*.sqlite k,
  owner @{HOME}/.config/gtk-3.0/bookmarks r,
  owner @{HOME}/.config/dconf/user w,
  owner /{,var/}run/user/*/dconf/user w,
  dbus (send)
       bus=session
       path=/org/gnome/GConf/Server
       member=GetDefaultDatabase
       peer=(label=unconfined),
  dbus (send)
       bus=session
       path=/org/gnome/GConf/Database/*
       member={AddMatch,AddNotify,AllEntries,LookupExtended,RemoveNotify}
       peer=(label=unconfined),
  dbus (send)
       bus=session
       path=/org/gtk/vfs/mounttracker
       interface=org.gtk.vfs.MountTracker
       member=ListMountableInfo
       peer=(label=unconfined),

  # gnome-session
  dbus (send)
       bus=session
       path=/org/gnome/SessionManager
       interface=org.gnome.SessionManager
       member={Inhibit,Uninhibit}
       peer=(label=unconfined),

  # unity screen API
  dbus (send)
       bus=system
       interface="org.freedesktop.DBus.Introspectable"
       path="/com/canonical/Unity/Screen"
       member="Introspect"
       peer=(label=unconfined),
  dbus (send)
       bus=system
       interface="com.canonical.Unity.Screen"
       path="/com/canonical/Unity/Screen"
       member={keepDisplayOn,removeDisplayOnRequest}
       peer=(label=unconfined),

  # freedesktop.org ScreenSaver
  dbus (send)
       bus=session
       path=/{,org/freedesktop/,org.gnome/}Screen{s,S}aver
       interface=org.freedesktop.ScreenSaver
       member={Inhibit,UnInhibit,SimulateUserActivity}
       peer=(label=unconfined),

  # gnome, kde and cinnamon screensaver
  dbus (send)
       bus=session
       path=/{,ScreenSaver}
       interface=org.{gnome.ScreenSaver,kde.screensaver,cinnamon.ScreenSaver}
       member=SimulateUserActivity
       peer=(label=unconfined),

  # UPower
  dbus (send)
       bus=system
       path=/org/freedesktop/UPower
       interface=org.freedesktop.UPower
       member=EnumerateDevices
       peer=(label=unconfined),

  #
  # Extensions
  # /usr/share/.../extensions/... is already covered by '/usr/** r', above.
  # Allow 'x' for downloaded extensions, but inherit policy for safety
  owner @{HOME}/.mozilla/**/extensions/** mixr,

  deny @{MOZ_LIBDIR}/update.test w,
  deny /usr/lib/mozilla/extensions/**/ w,
  deny /usr/lib/xulrunner-addons/extensions/**/ w,
  deny /usr/share/mozilla/extensions/**/ w,
  deny /usr/share/mozilla/ w,

  # Miscellaneous (to be abstracted)
  # Ideally these would use a child profile. They are all ELF executables
  # so running with 'Ux', while not ideal, is ok because we will at least
  # benefit from glibc's secure execute.
  /usr/bin/mkfifo Uxr,  # investigate
  /bin/ps Uxr,
  /bin/uname Uxr,
  
  ## firejail
  /run/firejail/lib/libpostexecseccomp.so mr,
  /run/firejail/mnt/seccomp/seccomp.postexec r,
  @{PROC}/*/fd/ r,
  /run/user/@{uid}/dconf/ rw,

  #/usr/bin/lsb_release Cxr -> lsb_release,
  #profile lsb_release {
  #  #include <abstractions/base>
  #  #include <abstractions/python>
  #  /usr/bin/lsb_release r,
  #  /bin/dash ixr,
  #  /usr/bin/dpkg-query ixr,
  #  /usr/include/python2.[4567]/pyconfig.h r,
  #  /etc/lsb-release r,
  #  /etc/debian_version r,
  #  /usr/share/distro-info/*.csv r,
  #  /var/lib/dpkg/** r,

  #  /usr/local/lib/python3.[0-6]/dist-packages/ r,
  #  /usr/bin/ r,
  #  /usr/bin/python3.[0-6] mr,

  #  # file_inherit
  #  deny /tmp/gtalkplugin.log w,
  #}
}

Here is one for Chromium, working with ungoogled-chromium on Arch Linux. I tried to minimize necessary permissions, and added support for KeepassXC in the chromium profile.

Again it was just pulled from Ubuntu repos and modified to run on Arch Linux.

# Author: Jamie Strandboge <jamie@canonical.com>
#include <tunables/global>

#@{chromium} = chromium{,-browser}
@{chromium} = chromium

# We need 'flags=(attach_disconnected)' in newer chromium versions
profile chromium_browser /usr/lib/@{chromium}/@{chromium} flags=(attach_disconnected) {
  #include <abstractions/audio>
  #include <abstractions/cups-client>
  #include <abstractions/dbus-session>
  #include <abstractions/dbus-strict>
  #include <abstractions/dconf>
  #include <abstractions/gnome>
  #include <abstractions/ibus>
  #include <abstractions/nameservice>
  #include <abstractions/user-tmp>

  # This include specifies which ubuntu-browsers.d abstractions to use. Eg, if
  # you want access to productivity applications, adjust the following file
  # accordingly.

  capability sys_admin,
  capability sys_chroot,
  capability sys_ptrace,

  ## UPower
  ## Not sure why these are needed, so deny for now
  ## Differnet on Arch Linux
  #deny dbus (send)
  #     bus=system
  #     path=/org/freedesktop/UPower
  #     interface=org.freedesktop.DBus.Properties
  #     member=Get
  #     peer=(label=unconfined),
  #deny dbus (send)
  #     bus=system
  #     path=/org/freedesktop/UPower/devices/*
  #     interface=org.freedesktop.DBus.Properties
  #     member=Get
  #     peer=(label=unconfined),
  #deny dbus (send)
  #     bus=system
  #     path=/org/freedesktop/UPower
  #     interface=org.freedesktop.UPower
  #     member={EnumerateDevices,GetDisplayDevice}
  #     peer=(label=unconfined),

  ## ???
  #deny dbus (send)
  #     bus=system
  #     path=/org/freedesktop/hostname1
  #     interface=org.freedesktop.DBus.Properties
  #     member=GetAll
  #     peer=(label=unconfined),

  # Networking
  network inet stream,
  network inet6 stream,
  @{PROC}/@{pid}/net/if_inet6 r,
  @{PROC}/@{pid}/net/ipv6_route r,

  # Should maybe be in abstractions
  /etc/mime.types r,
  /etc/mailcap r,
  /etc/mtab r,
  #/etc/xdg/xubuntu/applications/defaults.list r,
  #owner @{HOME}/.local/share/applications/defaults.list r,
  #owner @{HOME}/.local/share/applications/mimeinfo.cache r,
  /tmp/.X[0-9]*-lock r,

  @{PROC}/self/exe ixr,
  @{PROC}/@{pid}/fd/ r,
  @{PROC}/filesystems r,
  @{PROC}/vmstat r,
  @{PROC}/ r,
  @{PROC}/@{pid}/task/@{tid}/stat r,
  owner @{PROC}/@{pid}/cmdline r,
  owner @{PROC}/@{pid}/io r,
  owner @{PROC}/@{pid}/setgroups w,
  owner @{PROC}/@{pid}/{uid,gid}_map w,
  @{PROC}/@{pid}/smaps r,
  @{PROC}/@{pid}/stat r,
  @{PROC}/@{pid}/statm r,
  @{PROC}/@{pid}/status r,
  @{PROC}/@{pid}/task/@{tid}/status r,
  deny @{PROC}/@{pid}/oom_{,score_}adj w,
  @{PROC}/sys/kernel/yama/ptrace_scope r,
  @{PROC}/sys/net/ipv4/tcp_fastopen r,
  @{PROC}/sys/fs/inotify/max_user_watches r,

  # Newer chromium needs these now
  /etc/udev/udev.conf r,
  # Chromium appears to want all "uevent" files under /sys/devices/
  /sys/devices/**/uevent r,
  /sys/devices/system/cpu/cpufreq/policy*/cpuinfo_max_freq r,
  /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_max_freq r,
  /sys/devices/system/node/node*/meminfo r,
  /sys/devices/pci[0-9]*/**/class r,
  /sys/devices/pci[0-9]*/**/config r,
  /sys/devices/pci[0-9]*/**/device r,
  /sys/devices/pci[0-9]*/**/irq r,
  /sys/devices/pci[0-9]*/**/resource r,
  /sys/devices/pci[0-9]*/**/revision r,
  /sys/devices/pci[0-9]*/**/subsystem_device r,
  /sys/devices/pci[0-9]*/**/subsystem_vendor r,
  /sys/devices/pci[0-9]*/**/vendor r,
  /sys/devices/pci[0-9]*/**/removable r,
  /sys/devices/pci[0-9]*/**/block/**/size r,
  /sys/devices/virtual/block/**/removable r,
  /sys/devices/virtual/block/**/size r,
  /sys/devices/virtual/tty/tty*/active r,
  # This is requested, but doesn't seem to actually be needed so deny for now
  deny /run/udev/data/** r,

  # Needed for the crash reporter
  owner @{PROC}/@{pid}/auxv r,

  # chromium mmaps all kinds of things for speed.
  /etc/passwd m,
  /usr/share/fonts/TTF/**/*.tt[cf] m,
  /usr/share/fonts/**/*.pfb m,
  /usr/share/mime/mime.cache m,
  /usr/share/icons/**/*.cache m,
  owner /{dev,run}/shm/pulse-shm* m,
  owner @{HOME}/.local/share/mime/mime.cache m,
  owner /tmp/** m,

  @{PROC}/sys/kernel/shmmax r,
  owner /{dev,run}/shm/{,.}org.chromium.* mrw,
  owner /{,var/}run/shm/shmfd-* mrw,

  /usr/lib/@{chromium}/*.pak mr,
  /usr/lib/@{chromium}/locales/* mr,

  # Noisy
  deny /usr/lib/@{chromium}/** w,
  deny /var/cache/fontconfig/ w,

  # Allow ptracing ourselves and our helpers
  ptrace (trace) peer=@{profile_name},
  ptrace (trace) peer=@{profile_name}//xdgsettings,
  ptrace (trace) peer=lsb_release,

  # Make browsing directories work
  / r,
  /**/ r,

  # Allow access to documentation and other files the user may want to look
  # at in /usr
  /usr/{include,share,src}** r,

  # Default profile allows downloads to ~/Downloads and uploads from ~/Public
  owner @{HOME}/ r,
  owner @{HOME}/Public/ r,
  owner @{HOME}/Public/* r,
  owner @{HOME}/Downloads/ r,
  owner @{HOME}/Downloads/* rw,

  # For migration
  owner @{HOME}/.mozilla/firefox/profiles.ini r,
  owner @{HOME}/.mozilla/firefox/*/prefs.js r,

  # Helpers
  /usr/bin/xdg-open ixr,
  /usr/bin/gnome-open ixr,
  /usr/bin/gvfs-open ixr,
  /usr/bin/kdialog ixr,
  # TODO: xfce
  /usr/bin/keepassxc-proxy ixr,


  # Importing firefox settings (requires 'r' access to @{HOME}/.mozilla/**
  # which is provided by abstractions/ubuntu-browsers.d/user-files).
  /etc/firefox/profile/bookmarks.html r,
  owner @{HOME}/.mozilla/** k,

  # Chromium Policies
  /etc/@{chromium}/policies/managed/** r,
  /etc/libva.conf r,

  # Chromium configuration
  owner @{HOME}/.pki/nssdb/* rwk,
  owner @{HOME}/.cache/chromium/ rw,
  owner @{HOME}/.cache/chromium/** rw,
  owner @{HOME}/.cache/chromium/Cache/* mr,
  owner @{HOME}/.config/chromium/ rw,
  owner @{HOME}/.config/chromium/** rwk,
  owner @{HOME}/.config/chromium/**/Cache/* mr,
  owner @{HOME}/.config/chromium/Dictionaries/*.bdic mr,
  owner @{HOME}/.config/chromium/**/Dictionaries/*.bdic mr,
  @{HOME}/.icons/default/index.theme r,

  # Allow transitions to ourself and our sandbox
  /usr/lib/@{chromium}/@{chromium} ix,
  /usr/lib/@{chromium}/chrome-sandbox cx -> chromium_browser_sandbox,

  # Allow communicating with sandbox
  unix (receive, send) peer=(label=/usr/lib/@{chromium}/@{chromium}//chromium_browser_sandbox),

  /{usr/,}bin/ps Uxr,
  /usr/lib/@{chromium}/xdg-settings Cxr -> xdgsettings,
  /usr/bin/xdg-settings Cxr -> xdgsettings,
  /usr/bin/lsb_release Pxr -> lsb_release,

  # GSettings
  owner /{,var/}run/user/*/dconf/     rw,
  owner /{,var/}run/user/*/dconf/user rw,
  owner @{HOME}/.config/dconf/user r,

  # Magnet links
  /usr/bin/gio ixr,

  # Chrome Gnome Shell Integration
  /etc/chromium/native-messaging-hosts/org.gnome.chrome_gnome_shell.json r,
  /usr/bin/chrome-gnome-shell ixr,

  profile xdgsettings {
    #include <abstractions/bash>
    #include <abstractions/gnome>

    /{usr/,}bin/dash ixr,

    /etc/ld.so.cache r,
    /etc/ld.so.preload r,
    /etc/xdg/** r,
    /usr/bin/xdg-settings r,
    /usr/lib/@{chromium}/xdg-settings r,
    /usr/share/applications/*.desktop r,
    /usr/share/applications/*.list r,

    # Checking default browser
    /{usr/,}bin/grep ixr,
    /{usr/,}bin/head ixr,
    /{usr/,}bin/readlink ixr,
    /{usr/,}bin/sed ixr,
    /{usr/,}bin/tr ixr,
    /{usr/,}bin/which ixr,
    /usr/bin/basename ixr,
    /usr/bin/cut ixr,

    # Setting the default browser
    /{usr/,}bin/mkdir ixr,
    /{usr/,}bin/mv ixr,
    /{usr/,}bin/touch ixr,
    /usr/bin/dirname ixr,
    /usr/bin/gconftool-2 ix,
    /usr/bin/[gm]awk ixr,
    /usr/bin/xdg-mime ixr,
    owner @{HOME}/.local/share/applications/ w,
    owner @{HOME}/.local/share/applications/mimeapps.list* rw,
  }

  profile chromium_browser_sandbox {
    # Be fanatical since it is setuid root and don't use an abstraction
    /{usr/,}lib/libgcc_s.so* mr,
    /{usr/,}lib/@{multiarch}/libgcc_s.so* mr,
    /{usr/,}lib{,32,64}/libm-*.so* mr,
    /{usr/,}lib/@{multiarch}/libm-*.so* mr,
    /{usr/,}lib{,32,64}/libpthread-*.so* mr,
    /{usr/,}lib/@{multiarch}/libpthread-*.so* mr,
    /{usr/,}lib{,32,64}/libc-*.so* mr,
    /{usr/,}lib/@{multiarch}/libc-*.so* mr,
    /{usr/,}lib{,32,64}/libdl-*.so* mr,
    /{usr/,}lib/@{multiarch}/libdl-*.so* mr,
    /{usr/,}lib{,32,64}/libld-*.so* mr,
    /{usr/,}lib/@{multiarch}/libld-*.so* mr,
    /{usr/,}lib{,32,64}/librt-*.so* mr,
    /{usr/,}lib/@{multiarch}/librt-*.so* mr,
    /{usr/,}lib{,32,64}/ld-*.so* mr,
    /{usr/,}lib/@{multiarch}/ld-*.so* mr,
    /{usr/,}lib/tls/*/{cmov,nosegneg}/libm-*.so* mr,
    /{usr/,}lib/tls/*/{cmov,nosegneg}/libpthread-*.so* mr,
    /{usr/,}lib/tls/*/{cmov,nosegneg}/libc-*.so* mr,
    /usr/lib/libatomic.so* mr,
    /usr/lib/@{multiarch}/libatomic.so* mr,
    /usr/lib/libstdc++.so* mr,
    /usr/lib/@{multiarch}/libstdc++.so* mr,
    /etc/ld.so.preload r,
    /etc/ld.so.cache r,

    # Required for dropping into PID namespace. Keep in mind that until the
    # process drops this capability it can escape confinement, but once it
    # drops CAP_SYS_ADMIN we are ok.
    capability sys_admin,

    # All of these are for sanely dropping from root and chrooting
    capability chown,
    capability fsetid,
    capability setgid,
    capability setuid,
    capability dac_override,
    capability sys_chroot,

    capability sys_ptrace,
    ptrace (read, readby),

    signal (receive) peer=unconfined,
    signal peer=@{profile_name},
    signal (receive, send) set=("exists"),
    signal (receive) peer=/usr/lib/@{chromium}/@{chromium},

    unix (receive, send) peer=(label=/usr/lib/@{chromium}/@{chromium}),
    unix (create),
    unix peer=(label=@{profile_name}),
    unix (getattr, getopt, setopt, shutdown) addr=none,

    @{PROC}/ r,
    @{PROC}/@{pid}/ r,
    @{PROC}/@{pid}/fd/ r,
    deny @{PROC}/@{pid}/oom_adj w,
    deny @{PROC}/@{pid}/oom_score_adj w,
    @{PROC}/@{pid}/status r,
    @{PROC}/@{pid}/task/@{tid}/stat r,

    /usr/bin/@{chromium} r,
    /usr/bin/keepassxc-proxy ix,
    /usr/lib/@{chromium}/@{chromium} Px,
    /usr/lib/@{chromium}/chrome-sandbox mr,

    /dev/null rw,

    owner /tmp/** rw,
  }
}

I didn’t see any copyrights or licensing on it, so suppose it should be ok.

You could alternatively use firejail as was mentioned, and enable the firejail-default profile.

# aa-enforce firejail-default

Provided you’re running a version of firejail compiled with apparmor support.

You can also run the browser in a firejail sandbox while at the same time containing it with the AppArmor profile.

matthew@ryzen: ~ $ sudo aa-status
apparmor module is loaded.
15 profiles are loaded.
15 profiles are in enforce mode.
   /usr/bin/passwd
   /usr/lib/firefox/firefox
   /usr/sbin/cupsd
   /usr/sbin/sshd
   /usr/sbin/sshd//passwd
   /usr/sbin/useradd
   /usr/sbin/useradd//pam_tally2
   /usr/sbin/userdel
   avahi-daemon
   chromium_browser
   chromium_browser//chromium_browser_sandbox
   chromium_browser//xdgsettings
   dhcpcd
   firejail-default
   ping
0 profiles are in complain mode.
11 processes have profiles defined.
11 processes are in enforce mode.
   /usr/lib/chromium/chromium (2813) chromium_browser
   /usr/lib/chromium/chromium (2816) chromium_browser
   /usr/lib/chromium/chromium (2819) chromium_browser
   /usr/lib/chromium/chromium (2843) chromium_browser
   /usr/lib/chromium/chromium (2848) chromium_browser
   /usr/lib/chromium/chromium (2882) chromium_browser
   /usr/lib/chromium/chromium (2899) chromium_browser
   /usr/bin/keepassxc-proxy (2935) chromium_browser
   /usr/lib/chromium/chromium (2964) chromium_browser
   /usr/lib/chromium/chromium (3008) chromium_browser
   /usr/bin/keepassxc (2042) firejail-default
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

I don’t have a very big system with a lot of stuff on it.

matthew@ryzen: ~ $ sudo ps aux | grep chromium
matthew   2807  0.0  0.0   4296  2564 tty2     S+   22:31   0:00 /usr/bin/firejail /usr/bin/chromium --cipher-suite-blacklist=0xc013,0xc014,0xeaea,0x009c,0x009d,0x002f,0x0035,0x000a
matthew   2809  0.0  0.0   4296  2228 tty2     S+   22:31   0:00 /usr/bin/firejail /usr/bin/chromium --cipher-suite-blacklist=0xc013,0xc014,0xeaea,0x009c,0x009d,0x002f,0x0035,0x000a

It definitely works, and the web browser certainly presents a large attack surface.