Setting up debian-13-minimal templates with bash script

Continuing the discussion from Setting up debian-12-minimal and whonix-17 templates:

R4.3 is out and with it the new debian-13-minimal template. So I tried to adapt the script from my previous guide. Since there are some changes with the new whonix-18 templates of which I am not fully aware yet I excluded them form this guide.

With this script you will be able to easily setup your debian-13-minimal templates for different use cases (e.g. NETWORKING, VPN, APP, FLATPAK, SIGNAL-Desktop, MULLVAD-Browser; further explained in the menu when running the script).

As previously stated I am not an IT expert - just an interested user. I am sure there are better ways to write up the code. Feel free to test it and to give feedback. If you do not like my package selection you can very easily change it in the script. Please checkout my references to other community guides (highlighted when running the script)!

This script is written to be used with QubesOS R4.3. Run it as root in debian-13-minimal. You might want to use my script-injector (check out the link: Setting up dom0 after fresh install - onionizing repos and other little things ; you will find the script-injector at the end of the script). It allows you to inject scripts from dom0 into a template or vm.

template-setup.sh:

#!/bin/bash
#main menu
function mainmenu {
		echo -e "\e[32;1mWelcome to meta-installer. This script is meant to help you set up debian-12-minimal and whonix templates. Choose option to proceed:
		 	\r 1) Basic debian-13-minimal install
			\r 2) Advanced debian-13-minimal installs
			\r 3) Exit"
		read mainmenu_choice
		echo

		case $mainmenu_choice in
			1)			
			##preparing basic template.
				echo -e "\e[33;1mPreparing basic debian-13-minimal template install. The following steps will take place:
					\r- APT will be configured to not install recommended and suggested packages.
					\r- Template will be onionized.
					\r- Template will be upgraded through tor.
					\r- A selection of packages will be installed. Changed to your liking in script.
					\r- Preparing template to spoofing hostname.
					\r- Automatic deletion of empty QubesIncoming folders will be set up.
					\r- Directory for placing bash scrips (root user) will be created.
					\rPress Enter to continue or Strg+C to quit... \e[0m"
				read
			
			##configuring apt to not install recommended and suggested packages.
				cat <<- 'EOF' > /etc/apt/apt.conf.d/90no-recommends-no-suggests
					APT::Install-Recommends "0";
					APT::Install-Suggests "0";
				EOF
			
			##updating template.
				apt update
				echo
			
			##installing apt-transport-tor to onionize debian repositories in next step
				apt install -y apt-transport-tor
				echo
			
			##oninizing debian repositories. change according to your preferences
				cat <<- 'EOF' > /etc/apt/sources.list.d/qubes-r4.list
					# Main qubes updates repository
					#deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] https://deb.qubes-os.org/r4.3/vm trixie main
					#deb-src [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] https://deb.qubes-os.org/r4.3/vm trixie main
					# Qubes updates candidates repository
					#deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg] https://deb.qubes-os.org/r4.3/vm trixie-testing main
					#deb-src  [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ]  https://deb.qubes-os.org/r4.3/vm trixie-testing main
					# Qubes security updates testing repository
					#deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg] https://deb.qubes-os.org/r4.3/vm trixie-securitytesting main
					#deb-src  [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] https://deb.qubes-os.org/r4.3/vm trixie-securitytesting main
					# Qubes experimental/unstable repository
					#deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg] https://deb.qubes-os.org/r4.3/vm trixie-unstable main
					#deb-src  [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] https://deb.qubes-os.org/r4.3/vm trixie-unstable main
					# Qubes Tor updates repositories
					# Main qubes updates repository
					deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie main
					#deb-src  [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie main
					# Qubes updates candidates repository
					#deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie-testing main
					#deb-src  [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie-testing main
					# Qubes security updates testing repository
					#deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie-securitytesting main
					#deb-src  [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie-securitytesting main
					# Qubes experimental/unstable repository
					#deb [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie-unstable main
					#deb-src  [arch=amd64 signed-by=/usr/share/keyrings/qubes-archive-keyring-4.3.gpg ] tor+http://deb.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/r4.3/vm trixie-unstable main
				EOF
				cat <<- 'EOF' > /etc/apt/sources.list
					#deb https://deb.debian.org/debian trixie main contrib non-free-firmware
					deb tor+http://2s4yqjx5ul6okpp3f2gaunr2syex5jgbfpfvhxxbbjwnrsvbk5v3qbid.onion/debian trixie main contrib non-free-firmware
					#deb https://deb.debian.org/debian-security trixie-security main contrib non-free-firmware
					deb tor+http://5ajw6aqf3ep7sijnscdzw77t7xq4xjpsy335yb2wiwgouo7yfxtjlmid.onion trixie-security main contrib non-free-firmware
					#deb https://deb.debian.org/debian trixie-backports main contrib non-free-firmware
					deb tor+http://2s4yqjx5ul6okpp3f2gaunr2syex5jgbfpfvhxxbbjwnrsvbk5v3qbid.onion/debian trixie-backports main contrib non-free-firmware
				EOF
			
			##updating template through onionized repositories.
				apt update
				echo
			
			##upgrading template.
				apt upgrade -y
				echo
			
			##installing basic packages. change according to your preferences.
				apt install -y curl iftop libfido2-1 grub2 ncat nmap openssh-client pcscd qubes-core-agent-networking qubes-core-agent-thunar qubes-kernel-vm-support qubes-u2f qubes-usb-proxy ssh-askpass-gnome tcpdump thunar wakeonlan wget wireshark xfce4-notifyd xfce4-terminal zenity
				echo
			
			##setting PATH to /opt/bin for bash scripts on root level.
				cat <<- 'EOF' > /etc/profile.d/opt-bin.sh
					export PATH="/opt/bin:$PATH"
				EOF
			mkdir /opt/bin
			##setting up automatic deletion of empty QubesIncoming folders.
				cat <<- 'EOF' > /etc/systemd/system/clean-incoming.service
					[Unit]
					Description=Empty QubesIncoming
					[Service]
					Type=oneshot
					ExecStart=/usr/bin/bash -c "test ! -d /home/user/QubesIncoming || find '/home/user/QubesIncoming/' -mindepth 1 -type d -exec rmdir '{}' \;"
					RemainAfterExit=yes
					[Install]
					WantedBy=multi-user.target
				EOF
				systemctl enable clean-incoming
				systemctl start clean-incoming
				echo			
			
			##preparing template to spoofing hostname. See advanced TEMPLATE installs (NETWORKING TEMPLATE). 
			##Service/AppVM has to be rebooted at least once to take effect.
				cat <<- 'EOF' > /etc/systemd/system/spoofing-hostname.service
					[Unit]
					Description=spoofing-hostname
					[Service]
					ExecStart=/usr/bin/bash -c 'mkdir -p /rw/config/protected-files.d/ && echo -e "/etc/hosts\n/etc/hostname" > /rw/config/protected-files.d/protect_hostname.txt'
					RemainAfterExit=yes
					[Install]
					WantedBy=multi-user.target
				EOF
				systemctl enable spoofing-hostname
				systemctl start spoofing-hostname
				echo
			
			##finishing BASIC TEMPLATE install.
				echo -e	"\e[32;1mDEBIAN-13-MINIMAL basic TEMPLATE install successful! Rename template (e.g. d13m). Press ENTER to continue or Strg+C to quit... \e[0m"				
				read
				mainmenu
				;;
			
			2)
				submenu
				;;
			
			3)
				echo -e "Exiting! \e[0m"
				exit 0
				;;
			
			*)
				echo -e "Wrong choice. Choose again! \e[0m"
				mainmenu
				;;
		esac
}

##function for advanced TEMPLATE installs
function submenu {
		echo -e "\e[36;1mYou have successfully installed your basic debian-13-minimal. Now choose an advanced debian-13-minimal install. You can combine the installs. Just re-run the script:
			\r 1) NETWORKING TEMPLATE with (MAC and HOSTNAME spoofing)
			\r 2) VPN TEMPLATE
			\r 3) APP TEMPLATE
			\r 4) FLATPAK TEMPLATE
			\r 5) WAYDROID TEMPLATE
			\r 6) SIGNAL-Dektop TEMPLATE
			\r 7) MULLVAD-Browser TEMPLATE
			\r 8) GATEWAY TEMPLATE
			\r 9) Back to basic TEMPLATE install
			\r 10) Exit"
		read submenu_choice
		echo
		case $submenu_choice in

			1)
				echo -e "\e[33;1mPreparing NETWORKING TEMPLATE. The following will happen:
					\r- Networking packages will be installed
					\r- MAC will be spoofed
					\r- Hostname will be spoofed
					\rPress Enter to continue or Strg+C to quit... \e[0m"
				read

			##installing networking packages. change according to your prefernces.
				apt update
				apt install -y dnsmasq-base firmware-iwlwifi firmware-misc-nonfree qubes-core-agent-network-manager wpasupplicant
				echo

			##to fully disable ipv6 set template kernelopts to "ivp6.disable=1".
				echo -e "\e[33;1mIf you want to disable ipv6 set kernelopts in dom0 (optional):
					\r\e[35;5;1m$ qvm-prefs [vmname] kernelopts ipv6.disable=1\e[0m
					\r\e[33;1mPress ENTER to continue or Strg+C to quit... \e[0m"
				read

			##spoofing mac.
				cat <<- 'EOF' > /etc/NetworkManager/conf.d/00-macrandomize.conf
					[device]
					wifi.scan-rand-mac-address=yes
					[connection]
					wifi.cloned-mac-address=stable
					ethernet.cloned-mac-address=stable
					connection.stable-id=${CONNECTION}/${BOOT}
					ipv6.dhcp-duid=stable-uuid
					#use random IPv6 addresses per session / don't leak MAC via IPv6 (cf. RFC 4941):
					ipv6.ip6-privacy=2
				EOF

			##spoofing hostname.
				cat <<- 'EOF' > /etc/network/if-pre-up.d/00_hostname
					#!/bin/bash
					set -e -o pipefail
					if [ -f "/rw/config/protected-files.d/protect_hostname.txt" ] && rand="$RANDOM" && mv "/etc/hosts.lock" "/etc/hosts.lock.$rand" ; then
					name="PC-$rand"
					echo "$name" > /etc/hostname
					hostname "$name"
					if [ -e /etc/debian_version ]; then
					ipv4_localhost_re="127\.0\.1\.1"
					else
					ipv4_localhost_re="127\.0\.0\.1"
					fi
					sed -i "s/^\($ipv4_localhost_re\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
					sed -i "s/^\(::1\(\s.*\)*\s\).*$/\1${name}/" /etc/hosts
					fi
					exit 0
				EOF
				chmod +x /etc/network/if-pre-up.d/00_hostname
				touch /etc/hosts.lock
				echo -e "\e[36;1mDEBIAN-13-MINIMAL NETWORKING TEMPLATE install successful! Rename template (e.g. d13m-net).
					\r\e[36;1mPress ENTER to continue or Strg+C to quit..."
				read
				submenu
				;;

			2)
				echo -e "\e[33;1mPreparing VPN TEMPLATE! The following will happen: 
					\r- Networking and WIREGUARD packages will be installed.
					\r- Random VPN autostart will be implemented via systemd service.
					\rPress Enter to continue or Strg+C to quit... \e[0m"
				read
				echo
				apt update
				echo
			##installing networking and vpn packages//no MAC spoofing - it breaks the vpn!
				apt install -y qubes-core-agent-network-manager wireguard wireguard-tools wireshark
				echo
			##setting up autostart for random VPN as service.
				cat <<- 'EOF' > /etc/systemd/system/random-vpn.service
					[Unit]
					Description=random vpn
					After=network-online.target
					Wants=network-online.target
					[Service]
					Type=oneshot
					ExecStart=/usr/bin/bash -c "RANDOM_VPN=$(nmcli connection show | awk '/wireguard/ { print $1 }' | sort -R | head -n 1) && nmcli connection up $RANDOM_VPN" 
					RemainAfterExit=yes
					[Install]
					WantedBy=multi-user.target
				EOF
				systemctl enable random-vpn
				systemctl start random-vpn
				echo
			##script to install multiple wireguard configuration files and setting up firewall rules. run as root.	
				cat <<- 'EOF' > /opt/bin/wireguard-setup
					#!/bin/bash
					
					#delete old wiregurad connections
					mapfile -t old_wg < <(nmcli -t -f NAME,TYPE connection show | awk -F: '$2=="wireguard"{print $1}')
					for name in "${old_wg[@]}"; do
					  [ -n "$name" ] || continue
					  nmcli connection delete "$name"
					done
					
					#choose wireguard conf files you want to import
					selection="$(GTK_THEME=Adwaita:dark zenity --file-selection \
					  --title="Choose wireguard conf files you want to import (*.conf)" \
					  --multiple \
					  --separator="|" \
					  --file-filter="*.conf | *.conf" \
					  --file-filter="... | *" || true)"

					[ -n "${selection}" ] || exit 0
					IFS='|' read -r -a confs <<< "$selection"

					#nmcli file import
					for conf in "${confs[@]}"; do
					  nmcli connection import type wireguard file "$conf"
					done

					#deactivate autoconnect and discoonect all connections
					mapfile -t wg_names < <(nmcli -t -f NAME,TYPE connection show | awk -F: '$2=="wireguard"{print $1}')
					for name in "${wg_names[@]}"; do
					  nmcli connection modify "$name" connection.autoconnect no
					  nmcli connection down "$name" >/dev/null 2>&1 || true
					done

					zenity --info --text="Done.\nImported: ${#confs[@]}\nautoconnect deactivated."
					
					#setting up custom firewall rules.
					mkdir /rw/config/qubes-firewall.d
					read -p "Setting up firewall to provide killswitch. Do not forget to enable qubes-firewall service in qube settings. Input your cutsom DNS for leak protection (check wireguard conf files): " DNS
					cat <<- EOT > /rw/config/qubes-firewall.d/custom-firewall
						#!/bin/bash
						nft add rule qubes custom-forward oifname eth0 counter drop
						nft add rule ip6 qubes custom-forward oifname eth0 counter drop
						
						nft add chain qubes nat { type nat hook prerouting priority dstnat\; }
						nft add rule qubes nat iifname == "vif*" tcp dport 53 dnat "$DNS"
						nft add rule qubes nat iifname == "vif*" udp dport 53 dnat "$DNS"
					EOT
					chmod +x /rw/config/qubes-firewall.d/custom-firewall	
				EOF
				chmod +x /opt/bin/wireguard-setup		
				
				echo -e "\e[36;1mDEBIAN-13-MINIMAL VPN TEMPLATE install successful! Rename template (e.g. d13m-vpn). To set up your VPN qube run the wireguard-importer script as root. For further VPN setup follow this link:
					\r\e[35;5;1mhttps://forum.qubes-os.org/t/wireguard-vpn-setup/19141 \e[0m
					\r\e[36;1mPress ENTER to continue or Strg+C to quit... \e[0m"
				read
				submenu
				;;
			
			3)
				echo -e "\e[33;1mPreparing APP TEMPLATE! The following will happen:
					\r- Selection of app packages will be installed
					\rPress Enter to continue or Strg+C to quit... \e[0m"
				read
				echo
				apt update
				echo
			
			##installing app selection. change according to your preference.
				apt install -y adb basez bluetooth bluez blueman cups cryptsetup eog ffmpegthumbnailer firefox-esr gimp git gnome-disk-utility gnome-keyring gnome-screenshot gparted gtkhash gvfs-backends keepassxc kleopatra libarchive-tools libblockdev-crypto3 libgdk-pixbuf2.0-bin libreoffice linux-image-amd64 linux-headers-amd64 metadata-cleaner mousepad onionshare pciutils psmisc pipewire pipewire-alsa pipewire-audio pipewire-qubes printer-driver-gutenprint qubes-vm-recommended qtqr vlc simple-scan sshfs system-config-printer tigervnc-viewer thunderbird tumbler tumbler-plugins-extra xarchiver yubikey-personalization zbar-tools  
				echo
			
			##removing passwordless root which was installed with qubes-vm-recommended.
				apt remove -y qubes-core-agent-passwordless-root
				echo
				echo -e "\e[36;1mDEBIAN-13-MINIMAL APP TEMPLATE install successful! Rename template (e.g. d13m-app). Press ENTER to continue or Strg+C to quit... \e[0m"
				read
				submenu
				;;
			
			4)
				echo -e "\e[33;1mPreparing FLATPAK TEMPLATE! The following will happen:
					\r- Nescessary packages will be installed
					\r- Flathub repo will be added
					\r- Command to proxy flatpak will be created
					\r- Command to manually upgrade flatpaks will be created
					\rPress Enter to continue or Strg+C to quit... \e[0m"
				read
				echo
				apt update
				echo
			
			##installing nescessary packages. change according to your preferences.
				apt install -y flatpak gnome-software-plugin-flatpak linux-image-amd64 linux-headers-amd64
				echo
			
			##adding flatpakrepo
				export all_proxy=http://127.0.0.1:8082/
				flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
			
			##creating script to install flatpaks from FLATHUB in template
				echo
				cat <<- 'EOF' | tee /opt/bin/flathub-install >/dev/null
					#!/bin/sh
					echo "\e[33;1mTo install flatpak paste prompt line from FLATHUB:\e[0m" 
					read PROMPT_LINE
					export all_proxy=http://127.0.0.1:8082/
					$PROMPT_LINE
				EOF
				chmod +x /opt/bin/flathub-install
				echo
			
			##creating script to update flatpaks
				echo
				cat <<- 'EOF' | tee /opt/bin/flatpak-update >/dev/null
					#!/bin/sh
					export all_proxy=http://127.0.0.1:8082/ 
					flatpak update -y
				EOF
				chmod +x /opt/bin/flatpak-update
				echo
				echo -e "\e[36;1mDEBIAN-13-MINIMAL FLATPAK TEMPLATE install successful! Rename template (e.g. d13m-flatpak). For a more sophisticated setup check out the following link:
					\r\e[35;5;1mhttps://forum.qubes-os.org/t/flatpak-integration-in-qubes-os-templates/20984
					\r\e[36;1mPress ENTER to continue or Strg+C to quit... \e[0m"
				read
				submenu
				;;
			
			5)
				echo -e "\e[33;1mPreparing WAYDROID TEMPLATE! The script is based on a community guide: 
					\r\e[35;5;1mhttps://forum.qubes-os.org/t/waydroid-template/23356 \e[0m
					\r\e[33;1mPlease check for reference. Press Enter to continue or Strg+C to quit... \e[0m"
				read
			##installing waydroid
				apt install -y sway qubes-core-agent-networking pulseaudio ca-certificates extrepo linux-image-amd64 linux-headers-amd64
				https_proxy=http://127.0.0.1:8082 http_proxy=http://127.0.0.1:8082 extrepo enable waydroid
				apt update
				apt install -y waydroid pipewire-pulse

			##configuring waydroid not to sart in container
				mkdir -p /etc/systemd/system/waydroid-container.service.d
				cat <<- 'EOF' | tee /etc/systemd/system/waydroid-container.service.d/override.conf >/dev/null
				[Unit]
				ConditionPathExists=!/run/qubes/this-is-templatevm
				EOF

			##initializing waydroid
				https_proxy=http://127.0.0.1:8082 http_proxy=http://127.0.0.1:8082 waydroid init

			##installing waydroid clipboard support
				apt install -y curl unzip
				curl --proxy http://127.0.0.1:8082/ --tlsv1.2 --proto =https --max-time 180 https://codeload.github.com/cdown/clipnotify/zip/refs/heads/master -o clipnotify-master.zip
				unzip -j clipnotify-master.zip -d clipnotify
				cd clipnotify

			##building and installing clipnotify
				apt install -y build-essential libx11-dev libxtst-dev
				mkdir -p /opt/bin
				sed -i "s|/usr/local|/opt|g" Makefile
				make
				make install
				echo 'export PATH="/opt/bin:$PATH"' >> /etc/profile.d/opt-bin.sh

			##installing x11 and wayland clipboard cli tools
				apt install -y xclip wl-clipboard

			##configuring sway to run script that will automatically transfer clipboard content between X11 and Wayland on sway start
				echo "exec /opt/bin/x11-wl-clip.sh" > /etc/sway/config.d/99-x11-wl-clip.conf
				mkdir -p /opt/bin
				cat <<- 'EOF' | tee /opt/bin/x11-wl-clip.sh >/dev/null
				#!/bin/bash
				x11_wl='while DISPLAY=":0" clipnotify -s clipboard; do xclip -d ":0" -selection clipboard -o | wl-copy; done'
				wl_x11='wl-paste -nw xclip -d ":0" -selection clipboard'
				eval "${x11_wl}" &>/dev/null &
				eval "${wl_x11}" &>/dev/null
				pstree -A -p $$ | grep -Eow "[0-9]+" | xargs kill &>/dev/null
				EOF
				chmod +x /opt/bin/x11-wl-clip.sh

			##installing pyclip
				apt install -y xclip wl-clipboard pip python3-venv
				python3 -m venv /opt/venv/pyclip
				source /opt/venv/pyclip/bin/activate
				pip install --proxy http://127.0.0.1:8082 pyclip
				deactivate
				echo 'export PATH="$PATH:/opt/venv/pyclip/bin"' >> /etc/profile.d/python-venv.sh
				echo 'export PYTHONPATH="$PYTHONPATH:/opt/venv/pyclip/lib/python3.11/site-packages"' >> /etc/profile.d/python-venv.sh

			##configuring firewall
				cat <<- 'EOF' | tee /etc/systemd/system/waydroid-firewall.service >/dev/null
				[Unit]
				ConditionPathExists=!/run/qubes/this-is-templatevm
				PartOf=waydroid-container.service
				After=waydroid-container.service
				BindsTo=waydroid-container.service
				Requires=qubes-iptables.service
				After=qubes-iptables.service
				BindsTo=qubes-iptables.service
				[Service]
				Type=oneshot
				ExecStart=/usr/bin/bash -c "if (nft create chain ip qubes waydroid-input) &>/dev/null; then nft add rule ip qubes custom-input jump waydroid-input; fi"
				ExecStart=/usr/bin/bash -c "if (nft create chain ip qubes waydroid-forward) &>/dev/null; then nft add rule ip qubes custom-forward jump waydroid-forward; fi"
				ExecStart=/usr/sbin/nft add rule ip qubes waydroid-input iifname "waydroid0" meta l4proto {tcp, udp} th dport { 53, 67 } accept
				ExecStart=/usr/sbin/nft add rule ip qubes waydroid-forward iifname "waydroid0" oifgroup 1 accept
				ExecStart=/usr/sbin/nft add rule ip qubes waydroid-forward oifname "waydroid0" iifgroup 1 accept
				ExecStop=/usr/sbin/nft flush chain ip qubes waydroid-input
				ExecStop=/usr/sbin/nft flush chain ip qubes waydroid-forward
				RemainAfterExit=yes
				[Install]
				WantedBy=waydroid-container.service
				EOF
				systemctl daemon-reload
				systemctl enable waydroid-firewall.service

			##disabling window title bar
				echo "default_border none" > /etc/sway/config.d/94-disable-window-titlebar.conf
				perl -0777 -i -pe 's/(^\h*bar\s*|\v\h*bar\s*)(\{(?:(?>[^{}]+)|(?-1))*\})//g' /etc/sway/config

			##creating desktop file to start waydroid
				apt install -y x11-utils
				cat <<- 'EOF' | tee /opt/bin/sway-waydroid.sh >/dev/null
				#!/bin/bash
				sway &>/dev/null &
				WAYLAND_DISPLAY="wayland-1" XDG_SESSION_TYPE="wayland" DISPLAY=":1" waydroid first-launch &>/dev/null &
				for i in $(seq 1 3);
				do
				    if xwininfo -name "wlroots - X11-1" &>/dev/null; then
					break
				    fi
				    sleep 1
				done
				while xwininfo -name "wlroots - X11-1" &>/dev/null; do
				    sleep 2
				done
				WAYLAND_DISPLAY="wayland-1" XDG_SESSION_TYPE="wayland" DISPLAY=":1" waydroid session stop &>/dev/null
				pstree -A -p $$ | grep -Eow "[0-9]+" | xargs kill &>/dev/null
				EOF
				chmod +x /opt/bin/sway-waydroid.sh

				cat <<- 'EOF' | tee /usr/share/applications/Waydroid-Sway.desktop >/dev/null
				[Desktop Entry]
				Type=Application
				Name=Waydroid-Sway
				Exec=/opt/bin/sway-waydroid.sh
				Icon=waydroid
				Categories=X-WayDroid-App;
				X-Purism-FormFactor=Workstation;Mobile;
				EOF

			##creating script to install apk in waydroid
				cat <<- 'EOF' | tee /opt/bin/waydroid-install-apk >/dev/null
				#!/bin/sh
				WAYLAND_DISPLAY="wayland-1" XDG_SESSION_TYPE="wayland" DISPLAY=":1" waydroid app install $1
				EOF
				chmod +x /opt/bin/waydroid-install-apk

			##creating script to upgrade waydroid
				cat <<- 'EOF' | tee /opt/bin/waydroid-upgrade >/dev/null
				#!/bin/sh
				https_proxy=http://127.0.0.1:8082 http_proxy=http://127.0.0.1:8082 waydroid upgrade
				EOF
				chmod +x /opt/bin/waydroid-upgrade

			##creating script to reinitialize waydroid after kernel switch
				cat <<- 'EOF' | tee /opt/bin/waydroid-reinitialize >/dev/null
				#!/bin/sh
				https_proxy=http://127.0.0.1:8082 http_proxy=http://127.0.0.1:8082 waydroid init -f
				EOF
				chmod +x /opt/bin/waydroid-reinitialize

			##installing thunar file manager
				apt install -y thunar qubes-core-agent-thunar

			##enabling sound
				apt install -y pipewire-qubes

				echo -e "\e[36;1mDEBIAN-13-MINIMAL WAYDROID TEMPLATE install successful! Rename template (e.g. d13m-waydroid). The following bash commands were created:
					\r\e[35;5;1m'waydroid-install-apk' for installing apks in appvm running waydroid
					\r'waydroid-upgrade' for manual upgrade of waydroid in template
					\r'waydroid-reinitialize' for reinitializing waydroid after kernel switch \e[0m
					\r\e[36;1mPress ENTER to continue or Strg+C to quit... \e[0m"
				read
				submenu
				;;
			
			6)
				echo -e "\e[33;1mPreparing SIGNAL-Desktop TEMPLATE! The following will happen:
					\r- Nescessary packages will be installed from SIGNAL repository.
					\rPress Enter to continue or Strg+C to quit... \e[0m"
				read
				echo
				export https_proxy=http://127.0.0.1:8082 http_proxy=http://127.0.0.1:8082

				# NOTE: These instructions only work for 64-bit Debian-based
				# Linux distributions such as Ubuntu, Mint etc.

				# 1. Install our official public software signing key:
				wget -O- https://updates.signal.org/desktop/apt/keys.asc | gpg --dearmor > signal-desktop-keyring.gpg; 
				cat signal-desktop-keyring.gpg | sudo tee /usr/share/keyrings/signal-desktop-keyring.gpg > /dev/null

				# 2. Add our repository to your list of repositories:	
				wget -O signal-desktop.sources https://updates.signal.org/static/desktop/apt/signal-desktop.sources;
				cat signal-desktop.sources | sudo tee /etc/apt/sources.list.d/signal-desktop.sources > /dev/null

				# 3. Update your package database and install Signal:
				apt update && apt install -y signal-desktop linux-image-amd64 linux-headers-amd64
				
				echo -e "\e[36;1mDEBIAN-13-MINIMAL APP TEMPLATE install successful! Rename template (e.g. d13m-app). Press ENTER to continue or Strg+C to quit... \e[0m"
				read
				submenu
				;;
			
			7)
				echo -e "\e[33;1mPreparing MULLVAD-Browser TEMPLATE! The following will happen:
					\r- Nescessary packages will be installed from SIGNAL repository.
					\rPress Enter to continue or Strg+C to quit... \e[0m"
				read
				echo
				export https_proxy=http://127.0.0.1:8082 http_proxy=http://127.0.0.1:8082

				# Download the Mullvad signing key
				curl -fsSLo /usr/share/keyrings/mullvad-keyring.asc https://repository.mullvad.net/deb/mullvad-keyring.asc

				# Add the Mullvad repository server to apt
				echo "deb [signed-by=/usr/share/keyrings/mullvad-keyring.asc arch=$( dpkg --print-architecture )] https://repository.mullvad.net/deb/stable stable main" | tee /etc/apt/sources.list.d/mullvad.list

				# Install the package
				apt update
				apt install -y mullvad-browser linux-image-amd64 linux-headers-amd64
				
				echo -e "\e[36;1mDEBIAN-13-MINIMAL APP TEMPLATE install successful! Rename template (e.g. d13m-app). Press ENTER to continue or Strg+C to quit... \e[0m"
				read
				submenu
				;;
			
			8)
				echo -e "\e[33;1mPreparing GATEWAY TEMPLATE. The following will happen:
					\r- Networking packages will be installed
					\r- Service will be setup to flush nft rule set
					\rPress Enter to continue or Strg+C to quit... \e[0m"
				read
			##installing networking packages. change according to your preferences.
				apt update
				apt install -y dnsmasq-base firmware-iwlwifi firmware-misc-nonfree qubes-core-agent-network-manager wpasupplicant
				echo
			##to fully disable ipv6 set template kernelopts to "ivp6.disable=1".
				echo -e "\e[33;1mIf you want to disable ipv6 set kernelopts in dom0 (optional):
					\r\e[35;5;1m$ qvm-prefs [vmname] kernelopts ipv6.disable=1\e[0m
					\r\e[33;1mPress ENTER to continue or Strg+C to quit... \e[0m"
				read
			##flushing nft ruleset for passthrough
				cat <<- 'EOF' > /etc/systemd/system/flush-nft.service
					[Unit]
					Description=flush-nft
					After=network-online.target
					Wants=network-online.target
					[Service]
					Type=oneshot
					ExecStart=/usr/sbin/nft flush ruleset
					RemainAfterExit=yes
					[Install]
					WantedBy=multi-user.target
				EOF
				systemctl enable flush-nft
				systemctl start flush-nft
				echo
				echo -e "\e[36;1mDEBIAN-13-MINIMAL GATEWAY TEMPLATE install successful! Now you can use a VM to share internet to external devices.
					\r\e[36;1mEnable networking in VM and set up adapters accordingly. Rename template (e.g. d13m-gateway).
					\r\e[36;1mPress ENTER to continue or Strg+C to quit..."
				read
				submenu
				;;
			
			9)
				echo -e "Back to BASIC TEMPLATE install! \e[0m"
				mainmenu
				;;
			
			10)
				echo -e "Exiting! \e[0m"
				exit 0
				;;
	
			*)
				echo -e "Wrong choice. Choose again! \e[0m"
				submenu
				;;

		esac
}
#start script
mainmenu



https://forum.qubes-os.org/t/setting-up-dom0-after-fresh-install-onionizing-repos-and-other-little-things/32671

5 Likes

Good initiative, I would suggest that in the Flatpak installation section you add the option to choose to install apps in user space or system space, if possible.

Isn’t it bad to use apt update inside the qube?

nothing wrong with it.

What do you mean nothing wrong with it…

Or please do explain what one need to do in order for this to work properly

1 Like

I think that guidance refers just to apt upgrade.

For template qubes best practice is to use qubes-vm-update from dom0 instead of apt upgrade from within the template so that Qubes’s extra post-update triggers will fire, if needed. For non-template, non-standalone qubes I feel a direct apt upgrade is generally ok because they are ephemeral changes that don’t persist through a restart, though maybe there are catches to this.

I generally don’t run apt update directly in a template qube either, but I no longer remember if this is good practice or just superstition.

edit: immediately refuted by @dreamscomethrough’s post:

Warning: Updating with direct commands such as dnf update and apt update is not recommended, since these bypass built-in Qubes OS update security measures. Instead, we strongly recommend using the Qubes Update tool or its command-line equivalents

It literally says “Updating with direct commands such as dnf update and apt update is not recommended”

1 Like

A good research project for someone in the community: investigate and summarize in a new post the current state of affairs w.r.t updating/upgrading.

  • What makes a direct apt update / dnf upgrade --refresh undesirable?
  • What makes a direct apt upgrade / dnf upgrade undesirable?
  • Should you ever/never use qubes-dom0-update to update dom0 (I believe never, its current use is for installing new packages)?
  • Is Qubes Tools -> Qubes Update -> select dom0 & Update equivalent to sudo qubesctl --show-output state.sls update.qubes-dom0?
  • Gotchas re: using qubes-vm-update – a great tool but can be a little counterintuitive
  • For templates and standalones, Qubes Update and qubes-vm-update are equivalent, right?
  • More?

Then the post could be digested into a few pull requests to improve the official documentation.

1 Like

The someone could post an answer in here if he likes :smile:

Already answered here:

So:

  • you can
  • yes
  • yes
3 Likes

This script is made for handling templates. User space will be created when you create an appvm. Then you will still be able to install apps in user space.

Well, you have to use apt update at one point if you want to install packages especially after manipulating the sources.list . One could argue if upgrading should be done form dom0 or through the update tool. But for the initial setup of a template the debian security features seem to be enough for my threat model.

1 Like