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>

# This profile allows everything and only exists to give the
# application a name instead of having the label "unconfined"


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,

  deny / r,
  deny /home/user/Desktop**/ r,
  deny /home/user/Documents**/ r,
  deny /home/user/Pictures**/ r,
  deny /home/user/QubesIncoming**/ r,
  deny /home/user/Templates**/ r,
  deny /home/user/Videos**/ r,
  deny /home/user/Music**/ r,
  deny owner /home/*/.bash_logout r,
  deny owner /home/*/.bashrc r,
  deny owner /home/user/.profile r,
  deny owner /home/user/.xsession-errors r,

  /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,
  owner /home/user/Downloads/* r,
  owner /home/user/Downloads/* w,
  owner /proc/*/* w,
  owner /proc/*/cgroup r,
  owner /proc/*/cmdline r,
  owner /proc/*/stat r,
  owner /proc/*/task/** r,
  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,
  deny network,

  /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
9. Then run sudo aa-enforce /etc/apparmor.d/nautilus && sudo aa-enforce /etc/apparmor.d/firefox 12. 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 13. 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

"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 acess 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.