Apparmor profile for Qubes available!

So after many test and reading documentation about the syntax for apparmor i finally create some apparmor profiles specially for Qubes.

The goal of this post is to increase the security of a normal user without affecting his experience this the number #1 priority

For now there is only two profiles but i’m planning to add other profiles such as Brave,Librewolf,Mullvad-Browser,Network-Manager (for sys-net) and more !

  1. Start your debian template
  2. I recommend to use the kicksecure repository to get their apparmor package
  3. Do
 echo "Types: deb
URIs: https://deb.kicksecure.com
Suites: trixie
Components: main contrib non-free
Enabled: yes
Signed-By: /usr/share/keyrings/derivative.asc" | sudo tee /etc/apt/sources.list.d/derivative.sources

Or if you prefer to use their tor repository you can do

echo "Types: deb
URIs: tor+https://deb.kicksecure.com
Suites: trixie
Components: main contrib non-free
Enabled: yes
Signed-By: /usr/share/keyrings/derivative.asc" | sudo tee /etc/apt/sources.list.d/derivative.sources

You could use their onion repository here but updating packages in the future will be very slow.

By using the tor repository you will need sys-whonix or the tor package installed in your system to install their packages.

  1. Then open your terminal and install those packages in the debian template run
sudo apt-get -y install apparmor apparmor-utils apparmor-profiles apparmor-profiles-extra apparmor-profiles-kicksecure
  1. Shutdown the template

In order to make apparmor works correctly in Qubes you need to run this commands in dom0 :

qvm-prefs x kernelopts "swiotlb=2048 security=apparmor"

Replace “x” by the name of your template

  1. Start your templateVM open a terminal and confirm apparmor is running by doing as root
sudo aa-enabled

It must say “Yes” in that case you can continue the guide otherwise you have done something wrong.

  1. As root run this command to install the firefox apparmor profile
echo "abi <abi/4.0>,

include <tunables/global>


profile firefox /{usr/lib/firefox{,-esr,-beta,-devedition,-nightly},opt/firefox}/firefox{,-esr,-bin} {
  include <abstractions/audio>
  include <abstractions/totem>
  include if exists <local/firefox>

  capability sys_admin,
  capability sys_chroot,
  capability sys_ptrace,


  network inet dgram,
  network inet stream,
  network inet6 dgram,
  network inet6 stream,
  network netlink raw,

  deny owner @{user_share_dirs}/gvfs-metadata/{,*} r,
  deny @{run}/user/@{uid}/gnome-shell-disable-extensions w,
  deny @{PROC}/pressure/* r,
  deny /* r,
  deny  @{HOME}/ r,
  deny  @{HOME}/*/ r,
  deny  @{HOME}/.* r,
  owner @{HOME}/Downloads/      r,
  owner @{HOME}/Downloads/      w,
  owner @{HOME}/Downloads/**   r,
  owner @{HOME}/Downloads/**   w,


  /dev/udmabuf rw,
  /etc/dconf/db/local r,
  /etc/dconf/profile/user r,
  /etc/firefox/policies/policies.json r,
  /etc/ld.so.cache r,
  /etc/ld.so.preload r,
  /etc/mime.types r,
  /proc/pressure/memory r,
  /sys/devices/system/cpu/* r,
  /sys/devices/system/cpu/** r,
  /sys/fs/cgroup/user.slice/user-1000.slice/** r,
  /usr/bin/update-desktop-database mrix,
  /usr/bin/update-mime-database mrix,
  /usr/lib/firefox/crashhelper mrix,
  /usr/lib/firefox/firefox-bin mrix,
  /usr/lib/firefox/glxtest mrix,
  /var/cache/fontconfig/ rw,
  owner /home/user/.cache/mesa_shader_cache/* rw,
  owner /home/user/.cache/mesa_shader_cache/** r,
  owner /home/user/.cache/mesa_shader_cache/** w,
  owner /home/user/.cache/mozilla/ rw,
  owner /home/user/.cache/mozilla/*/ rw,
  owner /home/user/.cache/mozilla/firefox/** k,
  owner /home/user/.cache/mozilla/firefox/** r,
  owner /home/user/.cache/mozilla/firefox/** w,
  owner /home/user/.cache/mozilla/firefox/*/ rw,
  owner /home/user/.config/* r,
  owner /home/user/.config/* w,
  owner /home/user/.config/dconf/* r,
  owner /home/user/.config/mozilla/ rw,
  owner /home/user/.config/mozilla/** k,
  owner /home/user/.config/mozilla/** r,
  owner /home/user/.config/mozilla/** w,
  owner /home/user/.config/pulse/ rw,
  owner /home/user/.local/share/applications/ rw,
  owner /home/user/.local/share/applications/* w,
  owner /home/user/.local/share/mime/ rw,
  owner /home/user/.local/share/mime/packages/ rw,
  owner /home/user/.local/share/mime/packages/* w,
  owner /home/user/.zcompdump r,
  @{PROC}/@{pid}/net/arp r,
  @{PROC}/@{pid}/net/if_inet6 r,
  @{PROC}/@{pid}/net/route r,
  owner @{PROC}/@{pid}/cgroup r,
  owner @{PROC}/@{pid}/cmdline r,
  owner @{PROC}/@{pid}/environ r,
  owner @{PROC}/@{pid}/fd/ r,
  owner @{PROC}/@{pid}/gid_map w, # If kernel.unprivileged_userns_clone = 1
  owner @{PROC}/@{pid}/mountinfo r,
  owner @{PROC}/@{pid}/mounts r,
  owner @{PROC}/@{pid}/oom_score_adj w,
  owner @{PROC}/@{pid}/setgroups w, # If kernel.unprivileged_userns_clone = 1
  owner @{PROC}/@{pid}/smaps r,
  owner @{PROC}/@{pid}/stat r,
  owner @{PROC}/@{pid}/statm r,
  owner @{PROC}/@{pid}/task/ r,
  owner @{PROC}/@{pid}/task/@{tid}/comm rw,
  owner @{PROC}/@{pid}/task/@{tid}/stat r,
  owner @{PROC}/@{pid}/uid_map w, # If kernel.unprivileged_userns_clone = 1  owner /run/user/1000/dconf/* rw,
  owner /run/user/1000/pulse/ rw,

  userns,

} " | sudo tee /etc/apparmor.d/firefox 

  1. For Nautilus (file manager) do
echo "include <tunables/global>

profile nautilus /usr/bin/nautilus {
  include <abstractions/gio-open>
  include <abstractions/hosts_access>
  include <abstractions/nvidia>
  include <abstractions/totem>
  include if exists <local/nautilus>

  deny /*/ r,
  deny owner /home/user/.xsession-errors r,

  /dev/udmabuf rw,
  /etc/dconf/db/local r,
  /etc/dconf/profile/user r,
  /home/user/firefox rw,
  /sys/devices/system/cpu/** r,
  /usr/bin/qvm-open-in-vm Ux,
  /usr/bin/x86_64-linux-gnu-cpp-14 r,
  /usr/lib/qubes/qvm-copy-to-vm.gnome Ux,
  owner /home/** rw,
  owner /home/*/.bash_logout r,
  owner /home/*/.bashrc r,
  owner /home/*/.config/gtk-3.0/bookmarks w,
  owner /home/*/.config/gtk-4.0/* r,
  owner /home/*/.local/share/Trash/files/ rw,
  owner /home/*/.local/share/Trash/info/ rw,
  owner /home/*/.profile r,
  owner /home/*/Desktop/Documents/ rw,
  owner /home/*/Documents/Music/ rw,
  owner /home/*/Music/Videos/ rw,
  owner /home/user/.cache/mesa_shader_cache/** k,
  owner /home/user/.cache/mesa_shader_cache/** r,
  owner /home/user/.cache/mesa_shader_cache/** w,
  owner /home/user/.cache/mesa_shader_cache/*/ w,
  owner /home/user/.config/dconf/* r,
  owner /home/user/.local/share/Trash/ rw,
  owner /home/user/.local/share/nautilus/** k,
  owner /home/user/.local/share/nautilus/** rw,
  owner /home/user/.zcompdump r,
  owner /home/user/Documents/ rw,
  owner /home/user/Downloads/ r,
  owner /run/user/1000/dconf/* r,
  owner /run/user/1000/dconf/* w,
  owner /usr/share/nautilus-python/**/ rw,

  userns,

} " | sudo tee /etc/apparmor.d/nautilus
  1. Then run
sudo aa-enforce /etc/apparmor.d/nautilus && sudo aa-enforce /etc/apparmor.d/firefox
  1. If a error appear about a protocol you can ignore this error i don’t know why exactly it happen but run the 9 commands again until it stop complaining i had to run it 2 or 3 times to work
  2. It’s done now firefox and nautilus is running under apparmor with strict permissions

F.A.Q

“Do Qubes copy-vm menu entry works ?”

Yes i’ve tried and it works without any issue

Can i use firejail with your profiles ?

You shouldn’t do it in fact using firejail will only increase the possibility of an attack the creator of Firejail has said himself this

Don't use this on enterprise servers, or any other multiuser system. Firejail was built for single-user desktops.

Maybe you could use firejail with my apparmor profiles but i didn’t test to see if it works and i will never do it because i’ve tested firejail for a long time with Qubes and some applications wasn’t properly starting with firejail so it was running without any protection which make firejail useless for example Nautilus wasn’t launching with firejail so i have to find a trick to force Nautilus to run under firejail which is frustrating to do. There is a good reason why Tails , Whonix or Secureblue do not rely on firejail to secure a system they rely only on Apparmor or Selinux or Secureblue.

What’s the main advantage of using those apparmor profiles ?”

They increase the security of your system and reduce the possibility of an attack a lot more

For example Firefox can’t access to the root filsystem , Firefox can’t access the folder “QubesIncoming” (I’m not sure if a website can still see if the folder is present with javascript or something else i need a expert to tell me)

The only folder firefox can access is the Downloads folder.

Nautilus do not have internet access and can’t access to the root filesystem nautilus can only access to all folder inside the home directory.

The apparmor profile for Firefox and Nautilus is maybe not perfect if this is the case just tell me i will try my best to fix everything.

I think i will create a github repo in the future for the future apparmor profiles and maintain those profiles as long QubesOS survive. The next profile i’m planning to add will be Network-Manager and Brave and Thunar. But first i need to see if people have some issue with the firefox and nautilus profile.

Edit : Just to make sure your appvm and dispvm is really using apparmor go to the settings of both vm and click on “Services” then select “apparmor” and click on “apply”. It might be possible the apparmor service doesn’t appear in the list of Services in that case click on “(custom…)” and click on “Add” then type “apparmor” and apply.

Edit 2 : Added a explanation to tell the users to not use firejail

Edit 3 : I removed the “deny network” rule it make nautilus doesn’t work at all i will find a another way

5 Likes

Update : I added “Deny network,” in the nautilus profile the first profile was allowing network now it doesn’t. So now it’s impossible nautilus reach the network.

I’ve seen apparmor have a lot of rules to manage network connection here we could use that later to make sys-net more secure in the future i won’t lie i will need help for that my technical knowledge about how linux network work is limited specially on Qubes

Also i think we could use those rules to make browser such as Firefox and Brave more private by denying any telemetry from Brave and Firefox ? But it’s unclear to me what could happen in the future if we block know telemetry maybe the user could not anymore reach internet ?

Maybe you could take a look at apparmor profiles from ezjail too, it’s not easy to get a profile done right.

1 Like

Here are also good examples for apparmor profiles.

1 Like

Yeah apparmor is not easy it took me so many hours to create the apparmor profile for firefox and make some test… Have you tried my apparmor profiles ? Have you met any issue ? I’d like to have some feeback it would be great

Thanks i have tried multiples times his apparmor profile but it wasn’t working for me on Qubes but i forget to take a look at the syntax he’s using i will copy some value from him

It would be nice if Debian and Kicksecure templates already came with AppArmor. Or does it work by default in Kicksecure template?

Kicksecure came with apparmor and some profile enabled by default but there is no profile configured properly for Qubes

Update i have created a codeberg repository dkzkz/apparmor-qubes: Apparmor profile for debian template in Qubes - Codeberg.org

I will put any profile in the repository before put a profile in the repository i will test it to make sure no one have any problem

1 Like

I checked Kicksecure template – it includes apparmor profiles for all browsers from Browser Choice: Brave, Chromium, Mullvad, Firefox, and Tor.
But these profiles have no restrictions.
Essentially, this indicates that apparmor is hardly used in Kicksecure - out of more than 100 profiles, only 25 are in enforce mode.
Therefore, this guide is very important and useful.

Can you do as sudo cat /etc/apparmor.d/brave and sudo cat /etc/apparmor.d/firefox ? Then copy and paste the content here of both i need to see the content because i don’t think they’re enabled and configured or maybe i’m wrong ? I’m not using kicksecure so i don’t know.

Update brave apparmor profile is finished codeberg seem to be down so i uploaded the brave profile here

PS : The brave apparmor profile can’t run some extensions like keepassxc because brave is using command like @{bin}/touch and the cat command to make some extensions work but i think it’s insecure to allow a browser to do such things so i removed them. If you think it’s a bad idea from me to do that then tell me i will change that

I think i will create a another brave apparmor profile with those permissions to let a user use extensions i don’t know if it’s a good idea to do…

I could disable tor in brave with the apparmor profile but i don’t know if i should do it or not we could talk about that in the future

Like the firefox profile the brave profile can’t see the content of every home folder including QubesIncoming except Downloads brave can’t access to the content of all root filesystems

Next profile coming up : Librewolf , Bitwarden , Proton-pass

include <tunables/global>

@{name}            = brave{,-beta,-dev,-bin}
@{domain}          = com.brine.Brave org.chromium.Chromium
@{lib_dirs}        = /opt/brave{-bin,.com}{,/@{name}}
@{USER}            = user                # ← replace with the actual login name
@{config_dirs}     = @{HOME}/.config/BraveSoftware/Brave-Browser{,-Beta,-Dev}
@{cache_dirs}      = @{HOME}/.cache/BraveSoftware/Brave-Browser{,-Beta,-Dev}
@{user_config_dirs}= @{HOME}/.config
@{exec_path}       = @{lib_dirs}/@{name}

profile brave @{exec_path} flags=(attach_disconnected) {
  include <abstractions/audio>
  include <abstractions/bash>
  include <abstractions/postfix-common>
  include <abstractions/totem>
  include if exists <local/brave>

  deny capability dac_override,

  capability sys_admin,
  capability sys_ptrace,

  ptrace read peer=Xorg,
  ptrace read peer=unconfined,
  ptrace trace peer=brave,

  deny /* r,
  deny @{HOME}/ r,
  deny @{HOME}/*/ r,
  deny @{HOME}/.* r,

  /dev/udmabuf                         rw,
  /etc/dconf/db/local                  r,
  /etc/dconf/profile/*                 r,
  /etc/ld.so.cache                     r,
  /etc/ld.so.preload                   r,
  /etc/opt/chrome/native-messaging-hosts/* r,
  @{HOME}/.config/BraveSoftware/Brave-Browser/biahpgbdmdkfgndcmfiipgcebobojjkp/** mrix,
  /opt/brave.com/brave/brave           mrix,
  /opt/brave.com/brave/chrome-sandbox mrix,
  /opt/brave.com/brave/chrome_crashpad_handler mrix,

  @{PROC}/*/stat          r,
  @{PROC}/*/statm         r,
  @{PROC}/*/task/**      r,
  /proc/sys/fs/inotify/max_user_watches r,
  /proc/sys/kernel/yama/ptrace_scope    r,

  /sys/devices/system/cpu/*   r,
  /sys/devices/system/cpu/**  r,
  /sys/devices/virtual/tty/** r,

  /usr/bin/basename          mrix,
  /usr/bin/cut               mrix,
  /usr/bin/dash              ix,
  /usr/bin/gawk              mrix,
  /usr/bin/grep              mrix,
  /usr/bin/head              mrix,
  /usr/bin/ln                mrix,
  /usr/bin/mkdir             mrix,
  /usr/bin/mktemp            mrix,
  /usr/bin/realpath          mrix,
  /usr/bin/sed               mrix,
  /usr/bin/tr                mrix,
  /usr/bin/update-desktop-database mrix,
  /usr/bin/xdg-desktop-menu mrix,
  /usr/bin/xdg-icon-resource mrix,
  /usr/bin/xdg-mime          mrix,
  /usr/bin/xdg-settings      mrix,

  /usr/share/chromium/extensions/ r,
  /var/cache/fontconfig/          rw,
  /{media,mnt,opt,srv}/**        mr,

  @{PROC}                         r,
  @{PROC}/@{pids}/                r,
  @{exec_path}                    mrix,

  owner "@{HOME}/.config/BraveSoftware/Brave-Browser/Crash Reports/*" k,
  owner "@{HOME}/.config/BraveSoftware/Brave-Browser/Crash Reports/*" rw,

  owner /dev/shm/*               r,
  owner /dev/shm/*               w,
  owner /etc/opt/chrome/         rw,
  owner @{HOME}/.cache/BraveSoftware/          rw,
  owner @{HOME}/.cache/BraveSoftware/**        rw,
  owner @{HOME}/.cache/BraveSoftware/**/       rw,
  owner @{HOME}/.cache/mesa_shader_cache/*     rw,
  owner @{HOME}/.cache/mesa_shader_cache/**    r,
  owner @{HOME}/.cache/mesa_shader_cache/**    w,

  owner @{HOME}/.config/BraveSoftware/Brave-Browser/          rw,
  owner @{HOME}/.config/BraveSoftware/Brave-Browser/*        w,
  owner @{HOME}/.config/BraveSoftware/Brave-Browser/**       k,
  owner @{HOME}/.config/BraveSoftware/Brave-Browser/**       rw,
  owner @{HOME}/.config/BraveSoftware/Brave-Browser/*/       rw,
  owner @{HOME}/.config/dconf/*                               r,

  owner /opt/brave.com/brave/extensions/ mrw,

  owner @{PROC}/*/clear_refs   w,
  owner @{PROC}/*/cmdline      r,
  owner @{PROC}/*/gid_map      w,
  owner @{PROC}/*/mem          r,
  owner @{PROC}/*/setgroups    w,
  owner @{PROC}/*/smaps_rollup r,
  owner @{PROC}/*/uid_map      w,

  owner /run/user/1000/dconf/* rw,
  owner /run/user/1000/pulse/* rw,

  owner @{HOME}/.pki/               rw,
  owner @{HOME}/.pki/*/             rw,
  owner @{HOME}/.pki/nssdb/*        k,
  owner @{HOME}/.pki/nssdb/*        r,
  owner @{HOME}/.pki/nssdb/*        w,

  owner @{HOME}/Desktop/*          w,
  owner @{HOME}/Downloads/*        r,
  owner @{HOME}/Downloads/*        w,

  owner @{PROC}/@{pid}/fd/          r,
  owner @{PROC}/@{pid}/oom_{,score_}adj rw,

  owner @{cache_dirs}/BraveSoftware/ rw,
  owner @{config_dirs}/BraveSoftware/ rw,
  owner @{config_dirs}/WidevineCdm/libwidevinecdm.so mrw,
  owner @{user_config_dirs}/BraveSoftware/ rw,

  userns,
}


2 Likes

It’s unclear to me if it is a good idea to tell the user to do

apparmor_parser -r /path/to/your_profile

This load the apparmor policy we are using into the kernel to enforce the security at 100% but i don’t know if a future update from Debian could break the system of user template so i would not recommend to do it. But i will use the apparmor_parser -r myself and make some test for 1 month to see if it’s ok to do

Uploaded in the repository the brave profile

Added in the repository a explanation to install the apparmor profile

I would like some people test the profile to tell me if it’s working for you correctly

It seems it works

1 Like

By the way, friend. Please try creating an apparmor for anti-detect Donut Browser and Camoufox (from donat), after popular browsers

1 Like

@adrelanos Hi. Why not set apparmor to enforce mode for all browsers in the Browser Choice list for extra security in Kicksecure? And add a warning when updating the Tor browser reminding users to modify apparmor profile. Maybe there are reasons or nuances why this isn’t done? Or perhaps apparmor isn’t needed with sysmaint?

Thanks for testing ! I updated the firefox profile and the brave profile in the codeberg repository and in the post as well. They cannot anymore read and access any file or folder inside the home directory except the Downloads folder so make sure to use the new version.

Explanation of the update :

In the previous version i was using deny /home/QubesIncoming deny /home/user/Documents but it was not good. A user or program could create a folder and write data there and in that case the browser could access this folder because the apparmor profile in the previous version was only denying from specific folder. Now in this new version we deny access to every folders and files in home directory even hidden files in home such as .ssh .bash_history is denied access.

PS : Firefox will throw you a error “Error cannot access to Downloads” but you can download files there don’t worry it will work i need to fix this but i don’t know how for now. It’s because i added the “deny @home” rules

The brave profile is considered finish i won’t touch it anymore i think
The firefox profile need to be modified i need to remove the “/home/user/” and replace it by @home syntax like i did in the brave profile i will do it today.
The nautilus profile need to be modified i’d like to apply the “deny network,” rule but it break the app nautilus need to connect to something called “org.freedesktop” i need to find a workaround i will do it today.

I will do it but it’s not my priority. For now i’m trying to make the current profile perfect i need to create librewolf profile , thunar and profile for sys-net. Sys-net will be my #1 priority after librewolf and thunar

1 Like

Okay. Thanks. Don’t forget about Mullvad browser and Tor :slightly_smiling_face: I will be using your profiles on debian and kicksecure templates

I uploded the mullvad-browser profile on the repository it isn’t finish but it can be used but i don’t understand why ur asking a tor profile i thought whonix was already providing a TB browser profile installed and configured

1 Like