To reduce 90% of common post here i decided to learn to use salt on Qubes to provide pre-configured hardened template and browsers. I spend 3-4 days working on this.
What is salt ? Read here https://doc.qubes-os.org/en/latest/user/advanced-topics/salt.html but with simple term you can say it's a "advanced bash script" to setup your own config under Qubes
Once you have installed everything i recommend you to switch to this guide https://forum.qubes-os.org/t/qubes-os-live-mode-dom0-in-ram-non-persistent-boot-ram-wipe-protection-against-forensics-tails-mode-hardening-dom0-root-read-only-paranoid-security/38868
The guide target advanced Qubes users (for now) i will provide the same setup for noob users soon
The guide is using debian-13-minimal and fedora-43-minimal template so you will need to install those templates before starting
The debian/kicksecure salt file require sys-whonix to setup the template but the fedora salt file do not require sys-whonix
To use the "automatic installation" file you need to move the file inside dom0 with this command
``` qvm-run --pass-io <src-vm> 'cat /path/to/file_in_src_domain' > /path/to/file_name_in_dom0
To be more clear the command must look like this
qvm-run --pass-io fedora-43 'cat /home/user/Downlods/firefox.sls' > firefox.sls
Then do
```
sudo mv (name of the file) /srv/salt/
or you can use this guide to copy paste easily
The file must be put at /srv/salt/(name of the file).sls
The name of the file doesn't matter you can name the file ex.sls it will work
In dom0 open a terminal and do ``` sudo qubesctl state.apply librewolf
(**don't put "sls" at the end of the command**)
where x = the name of the file in /srv/salt/
**If you do not have enough ram the installation process will abort so don't open too much vm at the same time**.
**Features :**
:white_check_mark: Kernel hardening from Tails & Secureblue
:white_check_mark: Selinux automatic installation & enabled
:white_check_mark: Deny read access to root file system , home directories except Downloads and machine-id for browsers using my apparmor profiles
:white_check_mark: Dark theme enabled by default
:white_check_mark: Anonymize hostname at boot for Template, Appvm, Dispvm (**works only for deb/kicksecure template for now.. the script doesn't work in fedora template i don't know why**..)
:white_check_mark: Every installation of browsers will be done by using apt-transport-tor (**for deb based template**) because fedora do not provide this feature
:white_check_mark: Firefox is using **arkenfox user.js** and brave is hardened by default the browser profile is coming from [here](https://forum.qubes-os.org/t/set-custom-preferences-for-brave-browser-in-disposable-qube/27351/24) no telemetry , no ai enabled etc...
:white_check_mark: qvm-firewall enabled by default for the **Appvm** we allow only dns traffic , https , http trafic everything else will be drop
:white_check_mark: Minimize debian even more thanks to [qubist post](https://forum.qubes-os.org/t/minifying-debian-12-minimal-and-debian-13-minimal/24778)
:white_check_mark: Automatically install Ublock origin when firefox start (like librewolf)
:white_check_mark: Automatically setup wget proxy and curl proxy to install software in the template (works only in debian for unknow reason)
:white_check_mark: Apparmor enabled by default the browser , Nautilus and qubes features will use my apparmor profiles
[details="debian-brave-apparmor.sls"]
update-debian-minimal: qvm.run: - name: debian-13-minimal - cmd: | /bin/bash -c 'apt-get update && apt-get -y full-upgrade' - user: root - flags: - nogui - pass-io - require: - qvm: start-debian-minimal
shutdown-debian-minimal: qvm.shutdown: - name: debian-13-minimal - require: - qvm: update-debian-minimal
setup-transport: qvm.start: - name: debian-13-minimal - require: - qvm: shutdown-debian-minimal
fix-locale: qvm.run: - name: debian-13-minimal - cmd: | /bin/bash -c "sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && /usr/sbin/locale-gen" && \ sed -i 's/^# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ /usr/sbin/locale-gen - user: root - flags: - nogui - pass-io - require: - qvm: setup-transport
setup-tor: qvm.run: - name: debian-13-minimal - cmd: | /bin/bash -c 'apt-get -y install apt-transport-tor alacritty' - user: root - flags: - nogui - pass-io - require: - qvm: fix-locale
minimize-debian: qvm.run: - name: debian-13-minimal - cmd: | /bin/bash -c 'apt-get -y purge \ apt-transport-https \ apt-utils \ cpio \ cron \ cron-daemon-common \ debconf-i18n \ dhcpcd-base \ eatmydata \ fdisk \ ifupdown \ iproute2 \ iputils-ping \ less \ libcap2-bin \ libeatmydata1 \ libfdisk1 \ libgcrypt20 \ libidn2-0 \ libjansson4 \ libk5crypto3 \ libkeyutils1 \ libkrb5support0 \ libmnl0 \ libnewt0.52 \ libp11-kit0 \ libsemanage-common \ libsepol2 \ libslang2 \ libtext-iconv-perl \ libtirpc-common \ libxtables12 \ logrotate \ nftables \ tasksel \ whiptail \ xterm && apt-get -y autoremove' - user: root - flags: - nogui - pass-io - require: - qvm: setup-tor
shutdown-after-tor: qvm.shutdown: - name: debian-13-minimal - require: - qvm: minimize-debian
clone-base-apparmor: qvm.clone: - name: base-apparmor - source: debian-13-minimal - require: - qvm: shutdown-after-tor
config-apt: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/sources.list deb tor+https://deb.debian.org/debian trixie main contrib non-free-firmware deb tor+https://deb.debian.org/debian-security trixie-security main contrib non-free-firmware deb tor+https://deb.debian.org/debian trixie-backports main EOF' - user: root - flags: - nogui - pass-io - require: - qvm: clone-base-apparmor
enable-dark-theme:
qvm.run:
- name: base-apparmor
- cmd: |
/bin/bash -c 'cat <<EOF >/etc/environment
GTK_THEME=Adwaita:dark
QT_QPA_PLATFORMTHEME=qt5ct
QT_STYLE_OVERRIDE=Adwaita-dark
EOF'
- user: root
- flags:
- nogui
- pass-io
- require:
- qvm: config-apt
random-hostname: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat > /etc/rc.local << '"'"'EOF'"'"' #!/bin/bash # Anonymize hostname with random name at boot
RANDOM_HOSTNAME=$(cat /dev/urandom | tr -dc "a-z" | head -c 12)
echo "$RANDOM_HOSTNAME" > /etc/hostname
hostname "$RANDOM_HOSTNAME"
sed -i "s/^127\.0\.0\.1.*/127.0.0.1 $RANDOM_HOSTNAME localhost/" /etc/hosts
hostnamectl set-hostname "$RANDOM_HOSTNAME" 2>/dev/null || true
EOF'
- user: root
- flags:
- nogui
- pass-io
- require:
- qvm: enable-dark-theme
random-hostname-exec: qvm.run: - name: base-apparmor - cmd: chmod +x /etc/rc.local - user: root - flags: - nogui - pass-io - require: - qvm: random-hostname
config-apt-onion-qubes: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/sources.list.d/qubes-r4.list deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie main # Backup HTTPS repository (commented) #deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] https://deb.qubes-os.org/r4.3/vm trixie main" EOF' - user: root - flags: - nogui - pass-io - require: - qvm: random-hostname-exec
set-pinning-backports: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/preferences.d/backports Package: * Pin: release n=trixie-backports Pin-Priority: 900 EOF' - user: root - flags: - nogui - pass-io - require: - qvm: config-apt-onion-qubes
set-pinning-stable: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/preferences.d/stable Package: * Pin: release n=stable Pin-Priority: 500 EOF' - user: root - flags: - nogui - pass-io - require: - qvm: set-pinning-backports
update-base-apparmor: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'apt-get update && apt-get -y full-upgrade' - user: root - flags: - nogui - pass-io - require: - qvm: set-pinning-backports - qvm: set-pinning-stable
restart: qvm.shutdown: - name: base-apparmor - require: - qvm: update-base-apparmor
start-again: qvm.start: - name: base-apparmor - require: - qvm: restart
add-unstable-repo: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >>/etc/apt/sources.list deb tor+https://deb.debian.org/debian/ unstable main EOF' - user: root - flags: - nogui - pass-io - require: - qvm: start-again
create-apparmor-pinning: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/preferences.d/unstable-pin Package: apparm* python-appar python-libappar Pin: release a=unstable Pin-Priority: 990 Package: * Pin: release a=unstable Pin-Priority: 1 EOF' - user: root - flags: - nogui - pass-io - require: - qvm: add-unstable-repo
update-indexes-after-unstable: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'apt update' - user: root - flags: - nogui - pass-io - require: - qvm: create-apparmor-pinning
install-apparmor: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'apt install -y -t unstable apparmor apparmor-utils apparmor-profiles apparmor-profiles-extra' - user: root - flags: - nogui - pass-io - require: - qvm: update-indexes-after-unstable
shutdown-before-kernelopts: qvm.shutdown: - name: base-apparmor - require: - qvm: install-apparmor
set-apparmor-kernelopts: qvm.prefs: - name: base-apparmor - kernelopts: 'swiotlb=2048 apparmor=1 security=apparmor' - require: - qvm: shutdown-before-kernelopts
restart-base-apparmor: qvm.start: - name: base-apparmor - require: - qvm: set-apparmor-kernelopts
minimize-git: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'apt-get install --no-install-recommends -y git' - user: root - flags: - nogui - pass-io - require: - qvm: restart-base-apparmor
speed-boost-apparmor: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c ' tee -a /etc/apparmor/parser.conf > /dev/null <<EOF write-cache cache-loc /etc/apparmor/earlypolicy/ Optimize=compress-fast EOF ' - user: root - flags: - nogui - pass-io - require: - qvm: minimize-git
shutdown-base-apparmor-before-clone: qvm.shutdown: - name: base-apparmor - require: - qvm: speed-boost-apparmor
cloning-apparmor: qvm.clone: - name: debian-apparmor-brave - source: base-apparmor - flags: - shutdown
start-brave-template: qvm.start: - name: debian-apparmor-brave - require: - qvm: cloning-apparmor
install-curl-tor: qvm.run: - name: debian-apparmor-brave - cmd: 'apt-get -y install tor curl' - user: root - flags: - nogui - pass-io - require: - qvm: start-brave-template
disable-tor-service: qvm.run: - name: debian-apparmor-brave - cmd: 'systemctl disable tor' - user: root - flags: - nogui - pass-io - require: - qvm: install-curl-tor
download-brave-key: qvm.run: - name: debian-apparmor-brave - cmd: | bash -c "export all_proxy=http://127.0.0.1:8082/ && \ curl -fsSLo /usr/share/keyrings/brave-browser-archive-keyring.gpg \ https://brave-browser-apt-release.s3.brave4u7jddbv7cyviptqjc7jusxh72uik7zt6adtckl5f4nwy2v72qd.onion/brave-browser-archive-keyring.gpg" - user: root - flags: - nogui - pass-io - require: - qvm: disable-tor-service
add-brave-repo: qvm.run: - name: debian-apparmor-brave - cmd: | bash -c "export all_proxy=http://127.0.0.1:8082/ && \ curl -fsSLo /etc/apt/sources.list.d/brave-browser-release.sources \ https://brave-browser-apt-release.s3.brave4u7jddbv7cyviptqjc7jusxh72uik7zt6adtckl5f4nwy2v72qd.onion/brave-browser.sources" - user: root - flags: - nogui - pass-io - require: - qvm: download-brave-key
force-brave-onion-apt: qvm.run: - name: debian-apparmor-brave - cmd: | /bin/bash -c 'cat > /etc/apt/sources.list.d/brave-browser-release.sources << EOF Types: deb URIs: https://brave-browser-apt-release.s3.brave4u7jddbv7cyviptqjc7jusxh72uik7zt6adtckl5f4nwy2v72qd.onion Suites: stable Components: main Architectures: amd64 arm64 Signed-By: /usr/share/keyrings/brave-browser-archive-keyring.gpg EOF' - user: root - flags: - pass-io - nogui - require: - qvm: add-brave-repo
install-brave: qvm.run: - name: debian-apparmor-brave - cmd: | bash -c 'apt-get update && apt-get install -y brave-browser zenity ffmpeg libavcodec-extra pipewire-qubes qubes-core-agent-networking nautilus qubes-core-agent-nautilus && \ apt-get -y purge gnome-keyring && \ apt-get -y autoremove' - user: root - flags: - nogui - pass-io - require: - qvm: force-brave-onion-apt
setup-apparmor-profiles-dkzkz: qvm.run: - name: debian-apparmor-brave - cmd: | /bin/bash -c 'export all_proxy=http://127.0.0.1:8082/ && \ cd /tmp && \ git clone https://codeberg.org/dkzkz/apparmor-qubes && \ cd /tmp/apparmor-qubes/stable/browser/brave && \ mv bra* /etc/apparmor.d/ && \ mv /tmp/apparmor-qubes/stable/file-manager/nautilus /etc/apparmor.d/ && \ mv /tmp/apparmor-qubes/stable/display-vm/Xorg /etc/apparmor.d/Xorg && \ cd /tmp/apparmor-qubes/stable/qubes-scripts/ && \ mv q* /etc/apparmor.d/ && \ cd /tmp/apparmor-qubes/stable/xdg-open/ && \ mv open /etc/apparmor.d/' - user: root - flags: - nogui - pass-io - require: - qvm: install-brave
enable-brave-apparmor: qvm.run: - name: debian-apparmor-brave - cmd: | /bin/bash -c 'apparmor_parser -r /etc/apparmor.d/brav* && \ apparmor_parser -r /etc/apparmor.d/Xorg && \ apparmor_parser -r /etc/apparmor.d/qubes* && \ apparmor_parser -r /etc/apparmor.d/nautilus && \ apparmor_parser -r /etc/apparmor.d/open' - user: root - flags: - nogui - pass-io - require: - qvm: setup-apparmor-profiles-dkzkz
cleanup-apparmor-repo: qvm.run: - name: debian-apparmor-brave - cmd: 'rm -rf /tmp/apparmor-qubes' - user: root - flags: - nogui - pass-io - require: - qvm: enable-brave-apparmor
create-brave-dir:
qvm.run:
- name: debian-apparmor-brave
- cmd: 'mkdir -p /opt/brave.com/brave'
- user: root
- flags:
- nogui
- pass-io
- require:
- qvm: cleanup-apparmor-repo
setup-proxy-wget: qvm.run: - name: debian-apparmor-brave - cmd: | /bin/bash -c ' echo "proxy = http://127.0.0.1:8082" >> ~/.curlrc echo "use_proxy = on" >> ~/.wgetrc echo "http_proxy = 127.0.0.1:8082" >> ~/.wgetrc echo "https_proxy = 127.0.0.1:8082" >> ~/.wgetrc' - user: root - flags: - nogui - pass-io - require: - qvm: create-brave-dir
write-initial-preferences: qvm.run: - name: debian-apparmor-brave - cmd: | /bin/bash -c 'cd /tmp && \ wget https://codeberg.org/dkzkz/apparmor-qubes/raw/branch/main/install/salt/debian/apparmor/brave-browser/brave-browser.sls/initial_preferences && \ mv ini* /opt/brave.com/brave/' - user: root - flags: - nogui - pass-io - require: - qvm: setup-proxy-wget
create-policy-dir: qvm.run: - name: debian-apparmor-brave - cmd: 'mkdir -p /etc/brave/policies/managed' - user: root - flags: - nogui - pass-io - require: - qvm: write-initial-preferences
write-group-policy: qvm.run: - name: debian-apparmor-brave - cmd: | /bin/bash -c 'cat <<EOF >/etc/brave/policies/managed/GroupPolicy.json { "MetricsReportingEnabled": false } EOF' - user: root - flags: - nogui - pass-io - require: - qvm: create-policy-dir
make-skel-dir: qvm.run: - name: debian-apparmor-brave - cmd: 'mkdir -p /etc/skel/.config/BraveSoftware/Brave-Browser' - user: root - flags: - nogui - pass-io - require: - qvm: write-group-policy
write-skel-local-state: qvm.run: - name: debian-apparmor-brave - cmd: | /bin/bash -c 'cat <<EOF | sudo tee /etc/skel/.config/BraveSoftware/Brave-Browser/Local\ State > /dev/null { "background_mode": {"enabled": false}, "hardware_acceleration_mode": {"enabled": false}, "brave": { "p3a": {"enabled": false}, "stats": {"reporting_enabled": false} }, "default_apps": {"extensions": {}}, "extensions": { "theme": {"colors": {}} }, "sync_promo": {"user_skipped": true} } EOF' - user: root - flags: - nogui - pass-io - require: - qvm: make-skel-dir
shutdown-template: qvm.shutdown: - name: debian-apparmor-brave - require: - qvm: write-skel-local-state
set-template-colour: qvm.prefs: - name: debian-apparmor-brave - label: black - require: - qvm: shutdown-template
create-dvm: qvm.present: - name: brave-browser-dvm - template: debian-apparmor-brave - label: yellow - require: - qvm: set-template-colour
config-firewall: cmd.run: - name: | printf "action=accept specialtarget=dns action=accept proto=tcp dstports=443 action=accept proto=tcp dstports=80 action=accept proto=tcp dstports=9050 action=drop" | qubesd-query dom0 admin.vm.firewall.Set brave-browser-dvm
config-brave-dvm: qvm.prefs: - name: brave-browser-dvm - memory: 300 - maxmem: 3000 - template-for-dispvms: true - require: - qvm: create-dvm
enable-brave-appmenus-dispvm: qvm.features: - name: brave-browser-dvm - enable: - service.apparmor - appmenus-dispvm - require: - qvm: config-brave-dvm
hardening-dvm: qvm.features: - name: brave-browser-dvm - set: - anon-timezone: '1' - menu-items: brave-browser.desktop Alacritty.desktop - require: - qvm: enable-brave-appmenus-dispvm
[/details]
[details="debian-mullvad-apparmor.sls"]
update-debian-minimal: qvm.run: - name: debian-13-minimal - cmd: | /bin/bash -c 'apt-get update && apt-get -y full-upgrade' - user: root - flags: - nogui - pass-io - require: - qvm: start-debian-minimal
shutdown-debian-minimal: qvm.shutdown: - name: debian-13-minimal - require: - qvm: update-debian-minimal
setup-transport: qvm.start: - name: debian-13-minimal - require: - qvm: shutdown-debian-minimal
fix-locale: qvm.run: - name: debian-13-minimal - cmd: | /bin/bash -c "sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && /usr/sbin/locale-gen" && \ sed -i 's/^# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ /usr/sbin/locale-gen - user: root - flags: - nogui - pass-io - require: - qvm: setup-transport
setup-tor: qvm.run: - name: debian-13-minimal - cmd: | /bin/bash -c 'apt-get -y install apt-transport-tor alacritty' - user: root - flags: - nogui - pass-io - require: - qvm: fix-locale
minimize-debian: qvm.run: - name: debian-13-minimal - cmd: | /bin/bash -c 'apt-get -y purge \ apt-transport-https \ apt-utils \ cpio \ cron \ cron-daemon-common \ debconf-i18n \ dhcpcd-base \ eatmydata \ fdisk \ ifupdown \ iproute2 \ iputils-ping \ less \ libcap2-bin \ libeatmydata1 \ libfdisk1 \ libgcrypt20 \ libidn2-0 \ libjansson4 \ libk5crypto3 \ libkeyutils1 \ libkrb5support0 \ libmnl0 \ libnewt0.52 \ libp11-kit0 \ libsemanage-common \ libsepol2 \ libslang2 \ libtext-iconv-perl \ libtirpc-common \ libxtables12 \ logrotate \ nftables \ tasksel \ whiptail \ xterm && apt-get -y autoremove' - user: root - flags: - nogui - pass-io - require: - qvm: setup-tor
shutdown-after-tor: qvm.shutdown: - name: debian-13-minimal - require: - qvm: minimize-debian
clone-base-apparmor: qvm.clone: - name: base-apparmor - source: debian-13-minimal - require: - qvm: shutdown-after-tor
config-apt: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/sources.list deb tor+https://deb.debian.org/debian trixie main contrib non-free-firmware deb tor+https://deb.debian.org/debian-security trixie-security main contrib non-free-firmware deb tor+https://deb.debian.org/debian trixie-backports main EOF' - user: root - flags: - nogui - pass-io - require: - qvm: clone-base-apparmor
enable-dark-theme:
qvm.run:
- name: base-apparmor
- cmd: |
/bin/bash -c 'cat <<EOF >/etc/environment
GTK_THEME=Adwaita:dark
QT_QPA_PLATFORMTHEME=qt5ct
QT_STYLE_OVERRIDE=Adwaita-dark
EOF'
- user: root
- flags:
- nogui
- pass-io
- require:
- qvm: config-apt
random-hostname: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat > /etc/rc.local << '"'"'EOF'"'"' #!/bin/bash # Anonymize hostname with random name at boot
RANDOM_HOSTNAME=$(cat /dev/urandom | tr -dc "a-z" | head -c 12)
echo "$RANDOM_HOSTNAME" > /etc/hostname
hostname "$RANDOM_HOSTNAME"
sed -i "s/^127\.0\.0\.1.*/127.0.0.1 $RANDOM_HOSTNAME localhost/" /etc/hosts
hostnamectl set-hostname "$RANDOM_HOSTNAME" 2>/dev/null || true
EOF'
- user: root
- flags:
- nogui
- pass-io
- require:
- qvm: enable-dark-theme
random-hostname-exec: qvm.run: - name: base-apparmor - cmd: chmod +x /etc/rc.local - user: root - flags: - nogui - pass-io - require: - qvm: random-hostname
config-apt-onion-qubes: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/sources.list.d/qubes-r4.list deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie main # Backup HTTPS repository (commented) #deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] https://deb.qubes-os.org/r4.3/vm trixie main" EOF' - user: root - flags: - nogui - pass-io - require: - qvm: random-hostname-exec
set-pinning-backports: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/preferences.d/backports Package: * Pin: release n=trixie-backports Pin-Priority: 900 EOF' - user: root - flags: - nogui - pass-io - require: - qvm: config-apt-onion-qubes
set-pinning-stable: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/preferences.d/stable Package: * Pin: release n=stable Pin-Priority: 500 EOF' - user: root - flags: - nogui - pass-io - require: - qvm: set-pinning-backports
update-base-apparmor: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'apt-get update && apt-get -y full-upgrade' - user: root - flags: - nogui - pass-io - require: - qvm: set-pinning-backports - qvm: set-pinning-stable
restart: qvm.shutdown: - name: base-apparmor - require: - qvm: update-base-apparmor
start-again: qvm.start: - name: base-apparmor - require: - qvm: restart
add-unstable-repo: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >>/etc/apt/sources.list deb tor+https://deb.debian.org/debian/ unstable main EOF' - user: root - flags: - nogui - pass-io - require: - qvm: start-again
create-apparmor-pinning: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'cat <<EOF >/etc/apt/preferences.d/unstable-pin Package: apparm* python-appar python-libappar Pin: release a=unstable Pin-Priority: 990 Package: * Pin: release a=unstable Pin-Priority: 1 EOF' - user: root - flags: - nogui - pass-io - require: - qvm: add-unstable-repo
update-indexes-after-unstable: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'apt update' - user: root - flags: - nogui - pass-io - require: - qvm: create-apparmor-pinning
install-apparmor: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'apt install -y -t unstable apparmor apparmor-utils apparmor-profiles apparmor-profiles-extra' - user: root - flags: - nogui - pass-io - require: - qvm: update-indexes-after-unstable
shutdown-before-kernelopts: qvm.shutdown: - name: base-apparmor - require: - qvm: install-apparmor
set-apparmor-kernelopts: qvm.prefs: - name: base-apparmor - kernelopts: 'swiotlb=2048 apparmor=1 security=apparmor' - require: - qvm: shutdown-before-kernelopts
restart-base-apparmor: qvm.start: - name: base-apparmor - require: - qvm: set-apparmor-kernelopts
minimize-git: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c 'apt-get install --no-install-recommends -y git' - user: root - flags: - nogui - pass-io - require: - qvm: restart-base-apparmor
speed-boost-apparmor: qvm.run: - name: base-apparmor - cmd: | /bin/bash -c ' tee -a /etc/apparmor/parser.conf > /dev/null <<EOF write-cache cache-loc /etc/apparmor/earlypolicy/ Optimize=compress-fast EOF ' - user: root - flags: - nogui - pass-io - require: - qvm: minimize-git
shutdown-base-apparmor-before-clone: qvm.shutdown: - name: base-apparmor - require: - qvm: speed-boost-apparmor
clone-debian-13-minimal-to-mullvad-template: qvm.clone: - name: debian-apparmor-mullvad - source: base-apparmor - flags: - shutdown - require: - qvm: shutdown-base-apparmor-before-clone
start-mullvad-template: qvm.start: - name: debian-apparmor-mullvad - require: - qvm: clone-debian-13-minimal-to-mullvad-template
basic-tool-needed: qvm.run: - name: debian-apparmor-mullvad - cmd: 'apt-get -y install curl wget' - user: root - flags: - nogui - pass-io - require: - qvm: start-mullvad-template
setup-proxy-wget: qvm.run: - name: debian-apparmor-librewolf - cmd: | /bin/bash -c ' echo "proxy = http://127.0.0.1:8082" >> ~/.curlrc echo "use_proxy = on" >> ~/.wgetrc echo "http_proxy = 127.0.0.1:8082" >> ~/.wgetrc echo "https_proxy = 127.0.0.1:8082" >> ~/.wgetrc' - user: root - flags: - nogui - pass-io - require: - qvm: basic-tool-needed
download-mullvad-key: qvm.run: - name: debian-apparmor-mullvad - cmd: 'bash -c "export all_proxy=http://127.0.0.1:8082/ && curl -fsSLo /usr/share/keyrings/mullvad-keyring.asc https://repository.mullvad.net/deb/mullvad-keyring.asc"' - user: root - flags: - nogui - pass-io - require: - qvm: setup-proxy-wget
add-mullvad-repository: qvm.run: - name: debian-apparmor-mullvad - cmd: | /bin/bash -c 'echo "deb [signed-by=/usr/share/keyrings/mullvad-keyring.asc arch=$( dpkg --print-architecture )] tor+https://repository.mullvad.net/deb/stable stable main" | tee /etc/apt/sources.list.d/mullvad.list' - user: root - flags: - nogui - pass-io - require: - qvm: download-mullvad-key
update-for-mullvad: qvm.run: - name: debian-apparmor-mullvad - cmd: 'apt update' - user: root - flags: - nogui - pass-io - require: - qvm: add-mullvad-repository
install-mullvad-browser-nautilus: qvm.run: - name: debian-apparmor-mullvad - cmd: | /bin/bash -c 'apt-get -y install mullvad-browser ffmpeg libavcodec-extra pipewire-qubes nautilus qubes-core-agent-networking zenity qubes-core-agent-nautilus && \ apt-get -y purge gnome-keyring && \ apt-get -y autoremove' - user: root - flags: - nogui - pass-io - require: - qvm: update-for-mullvad
setup-apparmor-profiles-dkzkz: qvm.run: - name: debian-apparmor-mullvad - cmd: | /bin/bash -c 'export all_proxy=http://127.0.0.1:8082/ && \ cd /tmp && \ git clone https://codeberg.org/dkzkz/apparmor-qubes && \ cd /tmp/apparmor-qubes/stable/browser/mullvad-browser && \ mv mullv* /etc/apparmor.d/ && \ mv /tmp/apparmor-qubes/stable/file-manager/nautilus /etc/apparmor.d/ && \ mv /tmp/apparmor-qubes/stable/display-vm/Xorg /etc/apparmor.d/Xorg && \ cd /tmp/apparmor-qubes/stable/qubes-scripts/ && \ mv q* /etc/apparmor.d/ && \ cd /tmp/apparmor-qubes/stable/xdg-open/ && \ mv open /etc/apparmor.d/' - user: root - flags: - nogui - pass-io - require: - qvm: install-mullvad-browser-nautilus
enable-mullvad-apparmor: qvm.run: - name: debian-apparmor-mullvad - cmd: | /bin/bash -c 'apparmor_parser -r /etc/apparmor.d/mullvad* && \ apparmor_parser -r /etc/apparmor.d/Xorg && \ apparmor_parser -r /etc/apparmor.d/qubes* && \ apparmor_parser -r /etc/apparmor.d/nautilus && \ apparmor_parser -r /etc/apparmor.d/open' - user: root - flags: - nogui - pass-io - require: - qvm: setup-apparmor-profiles-dkzkz
remove-cloned-repository: qvm.run: - name: debian-apparmor-mullvad - cmd: 'rm -rf /tmp/apparmor-qubes' - user: root - flags: - nogui - pass-io - require: - qvm: enable-mullvad-apparmor
shutdown-mullvad-template: qvm.shutdown: - name: debian-apparmor-mullvad - require: - qvm: remove-cloned-repository
set-template-color-black: qvm.prefs: - name: debian-apparmor-mullvad - label: black - require: - qvm: shutdown-mullvad-template
create-apparmor-mullvad-browser-dvm: qvm.present: - name: mullvad-browser-dvm - template: debian-apparmor-mullvad - label: yellow - require: - qvm: set-template-color-black
config-firewall: cmd.run: - name: | printf "action=accept specialtarget=dns action=accept proto=tcp dstports=443 action=accept proto=tcp dstports=80 action=drop" | qubesd-query dom0 admin.vm.firewall.Set mullvad-browser-dvm
configure-mullvad-dvm: qvm.prefs: - name: mullvad-browser-dvm - template-for-dispvms: true - memory: 300 - maxmem: 3000 - require: - qvm: create-apparmor-mullvad-browser-dvm
enable-mullvad-appmenus-dispvm: qvm.features: - name: mullvad-browser-dvm - enable: - appmenus-dispvm - service.apparmor - require: - qvm: configure-mullvad-dvm
add-mullvad-browser-menu: qvm.features: - name: mullvad-browser-dvm - set: - anon-timezone: '1' - menu-items: mullvad-browser.desktop Alacritty.desktop - require: - qvm: enable-mullvad-appmenus-dispvm ``` [/details]
I provide only two files because there is more than ~ 3 500 lines for all salt files and if i have to edit the post to update the content it would be painful for me almost impossible
To get the kicksecure version only brave for now go on my repo To get the debian version go on my codeberg repo To get the fedora version go on my codeberg repo To get the fedora Selinux version go on my codeberg repo
Technical details information
Every files have the same logic.
Know issue :
Missing :
❌ A salt file to automatically update the apparmor profile from my repository to the template (i will do it soon) ❌ Librewolf is not in dark mode on fedora or debian i forget which one ❌ I'm not really sure if the qvm-features anon-timezone 1 is properly working in my testing i get the same issue as https://forum.qubes-os.org/t/anon-timezone-doesnt-work-for-me/39539 i enabled anon-timezone 1 for every salt file but my timezone didn't change when i tested on website like https://browserleaks.com/
Feel free to contact me on element @aatrfs76519:nope.chat for any suggestion about the guide
The curl and wget proxy The dark theme Brave browser hardened is coming from here To setup arkenfox js and ublock for firefox i used my own guide The qvm-firewall is coming from this discussion