I do not know in which direction your reply goes. At least someone who works in internet businesses HAS to pay his rent and buy some food. What is your idea, where the money should come from?
This is completely offtopic.
@deeplow, please split topic from here into All Around Qubes or elswhere. Possible subject - “Is it moral and/or legal to use addblocks and other SPA tools in Qubes”
@ruedi this forum is exclusively for Qubes-related discussions. Other venues like reddit.com/r/privacy may be more suited.
Hi, since I am new to forum regulations I do make mistakes, but I should have known better.
I deleted the off-topic section. Hope that’s ok.
Thanks BEBF738VD for the guide.
Have any Fedora template users figured out an elegant way to integrate updater.sh and user-overrides.js into this process? It would be nice to have a way to automatically check if user.js is up to date, then update user.js if it is not, and finally apply user-overrides.js. Having to manually maintain each VM sounds like a lot of work. I am still a bit new to linux so I am not sure how to accomplish this.
edit: I might switch to firefox-esr to have more supported options in policies.json and to reduce amount of maintenance required. Please correct me if I am wrong, but it looks like the commands in the OP do not include a method to activate deprecated user.js prefs that ESR uses. edit2: turns out the commands DO activate deprecated user.js prefs for ESR.
@Vr3th @clarinetthelionking The link that Vr3th provided is accurate. I checked it against mozilla’s documentation. I only had issues including my ublock config in policies.json. However this article helped solve these issues. I configured ublock to my liking in an existing browser, then used ublock’s “Back up to file” setting to generate a backup file. Pasted this backup into the adminSetting utility mentioned in the article. Then pasted the output plain string value into policies.json like so:
{
"3rdparty": {
"Extensions": {
"ublock0@raymondhill.net": {
"adminSettings": {"userSettings":{"OTHER/SETTINGS/HERE"..."}
}
}
}
}
Now everything is working in all VMs based on the Fedora template.
No worries!
Interesting.
If they are trying to fingerprint based on the speed a GPU renders whatever would a way to mask this be to randomize the clock speed of your GPU? I don’t know much but about this sort of thing but I would assume it would be hard to impossible to make any judgements based of render speed if the clock speed and maybe ram timing of a GPU was randomized or at least changed from time to time.
Just a thought.
How can I make extensions to get “silently” granted with all the necessary permissions not requiring to me to see any splash screens about first use etc?
Here’s an addition of caching Firefox addons to install addons using policies.json.
The new DispVMs on boot will request caching VM to get the Firefox addons before Firefox will start.
Caching VM on receiving request will get the latest addon version info and check the addon on disk if it’s the latest version. It’ll download the addon if the version on disk is not the latest. Then it’ll send the latest addon to the requester.
Example for uBlock Origins.
Change sys-whonix in /usr/local/bin/firefox-get-addons in disposable template and in /etc/qubes/policy.d/30-user.policy in dom0 to your desired VM that will be processing the requests to get the Firefox addons.
Change debian-11-dvm in dom0 qvm-tags to your desired disposable template.
To make disposable VMs based on other disposable templates use the caching VM you need to repeat step 1 in new disposable template and add firefox tag to it in dom0:
qvm-tags debian-11-firefox-dvm add tag firefox
1. In disposable template (debian-11-dvm in this example):
Run as user:
mkdir -p /home/user/.config/systemd/user
cat << 'EOF' | sudo tee /usr/local/bin/firefox-get-addons
#!/bin/sh
qubes_vm_name="$(qubesdb-read /name)"
# Check that we're not running inside Disposable Template
if echo "$qubes_vm_name" | grep -q --invert-match "\-dvm" ; then
/usr/lib/qubes/qrexec-client-vm --filter-escape-chars-stderr -- sys-whonix user.FirefoxGetAddon+uBlockOrigin /usr/lib/qubes/qfile-unpacker
fi
EOF
sudo chmod +x /usr/local/bin/firefox-get-addons
mkdir -p /home/user/.config/systemd/user
cat << 'EOF' > /home/user/.config/systemd/user/firefox-get-addons.service
[Unit]
Description=Get Firefox Add-ons
Before=basic.target
DefaultDependencies=no
[Service]
Type=oneshot
Environment=QREXEC_REMOTE_DOMAIN=dom0
ExecStart=/usr/local/bin/firefox-get-addons
[Install]
WantedBy=basic.target
EOF
systemctl --user daemon-reload
systemctl --user enable firefox-get-addons.service
Add extension to install in ExtensionSettings in policies.json file:
"ExtensionSettings": {
"*": {
"installation_mode": "blocked"
},
"uBlock0@raymondhill.net": {
"installation_mode": "normal_installed",
"install_url": "file:///home/user/QubesIncoming/dom0/ublock_origin-latest.xpi"
}
},
2. In your caching VM (sys-whonix in this example):
Run as user:
sudo mkdir -p /usr/local/etc/qubes-rpc
cat << 'EOF' | sudo tee /usr/local/etc/qubes-rpc/user.FirefoxGetAddon+uBlockOrigin
#!/usr/bin/env python3
import os
import sys
import json
import requests
import shutil
import hashlib
import subprocess as s
def download_file(url,proxies,filename):
with requests.get(url, proxies=proxies, stream=True) as r:
with open(filename, 'wb') as f:
shutil.copyfileobj(r.raw, f)
def sha256sum(filename):
h = hashlib.sha256()
b = bytearray(128*1024)
mv = memoryview(b)
with open(filename, 'rb', buffering=0) as f:
while n := f.readinto(mv):
h.update(mv[:n])
return h.hexdigest()
def main():
# Set Tor proxy if we're running in Whonix VM
if os.path.exists('/usr/share/whonix/marker'):
proxy = 'socks5h://127.0.0.1:9050'
else:
proxy = ''
proxies = {
'http': proxy,
'https': proxy
}
url = 'https://addons.mozilla.org/api/v5/addons/addon/ublock-origin/versions/?page_size=1'
response = requests.get(url, proxies=proxies)
addon_latest_json = response.json()['results'][0]
addon_dest_file = '/home/user/Downloads/firefox-extensions/ublock_origin-latest.xpi'
os.makedirs(os.path.dirname(addon_dest_file), exist_ok=True)
if not os.path.exists(addon_dest_file) or sha256sum(addon_dest_file) != addon_latest_json['file']['hash'].split(':')[1]:
download_file(addon_latest_json['file']['url'], proxies, addon_dest_file)
if not os.path.exists(addon_dest_file) or sha256sum(addon_dest_file) != addon_latest_json['file']['hash'].split(':')[1]:
s.call(['notify-send','Failed to get latest uBlock Origin Firefox addon','--icon=dialog-error'])
sys.exit(1)
s.call(['/usr/lib/qubes/qfile-agent',addon_dest_file])
sys.exit(0)
if __name__ == '__main__':
main()
EOF
3. In dom0:
Run as user:
cat << 'EOF' | sudo tee -a /etc/qubes/policy.d/30-user.policy
user.FirefoxGetAddon +uBlockOrigin @tag:firefox sys-whonix allow
EOF
qvm-tags debian-11-dvm add tag firefox
Fixed to use ExtensionSettings instead of Extensions in policies.json:
Updated copy here
Here’s an addition of caching Firefox addons to install addons using policies.json.
The new DispVMs on boot will request caching VM to get the Firefox addons before Firefox will start.
Caching VM on receiving request will get the latest addon version info and check the addon on disk if it’s the latest version. It’ll download the addon if the version on disk is not the latest. Then it’ll send the latest addon to the requester.
Example for uBlock Origins.
Change sys-whonix in /usr/local/bin/firefox-get-addons in disposable template and in /etc/qubes/policy.d/30-user.policy in dom0 to your desired VM that will be processing the requests to get the Firefox addons.
Change debian-11-dvm in dom0 qvm-tags to your desired disposable template.
To make disposable VMs based on other disposable templates use the caching VM you need to repeat step 1 in new disposable template and add firefox tag to it in dom0:
qvm-tags debian-11-firefox-dvm add tag firefox
1. In disposable template (debian-11-dvm in this example):
Run as user:
mkdir -p /home/user/.config/systemd/user
cat << 'EOF' | sudo tee /usr/local/bin/firefox-get-addons
#!/bin/sh
qubes_vm_name="$(qubesdb-read /name)"
# Check that we're not running inside Disposable Template
if echo "$qubes_vm_name" | grep -q --invert-match "\-dvm" ; then
/usr/lib/qubes/qrexec-client-vm --filter-escape-chars-stderr -- sys-whonix user.FirefoxGetAddon+uBlockOrigin /usr/lib/qubes/qfile-unpacker
fi
EOF
sudo chmod +x /usr/local/bin/firefox-get-addons
mkdir -p /home/user/.config/systemd/user
cat << 'EOF' > /home/user/.config/systemd/user/firefox-get-addons.service
[Unit]
Description=Get Firefox Add-ons
Before=default.target
[Service]
Type=oneshot
Environment=QREXEC_REMOTE_DOMAIN=dom0
ExecStart=/usr/local/bin/firefox-get-addons
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable firefox-get-addons.service
Add extension to install in ExtensionSettings in policies.json file:
"ExtensionSettings": {
"*": {
"installation_mode": "blocked"
},
"uBlock0@raymondhill.net": {
"installation_mode": "normal_installed",
"install_url": "file:///home/user/QubesIncoming/dom0/ublock_origin-latest.xpi"
}
},
2. In your caching VM (sys-whonix in this example):
Run as user:
sudo mkdir -p /usr/local/etc/qubes-rpc
cat << 'EOF' | sudo tee /usr/local/etc/qubes-rpc/user.FirefoxGetAddon+uBlockOrigin
#!/usr/bin/env python3
import os
import sys
import json
import requests
import shutil
import hashlib
import subprocess as s
def download_file(url,proxies,filename):
with requests.get(url, proxies=proxies, stream=True) as r:
with open(filename, 'wb') as f:
shutil.copyfileobj(r.raw, f)
def sha256sum(filename):
h = hashlib.sha256()
b = bytearray(128*1024)
mv = memoryview(b)
with open(filename, 'rb', buffering=0) as f:
while n := f.readinto(mv):
h.update(mv[:n])
return h.hexdigest()
def main():
# Set Tor proxy if we're running in Whonix VM
if os.path.exists('/usr/share/whonix/marker'):
proxy = 'socks5h://127.0.0.1:9050'
else:
proxy = ''
proxies = {
'http': proxy,
'https': proxy
}
url = 'https://addons.mozilla.org/api/v5/addons/addon/ublock-origin/versions/?page_size=1'
response = requests.get(url, proxies=proxies)
addon_latest_json = response.json()['results'][0]
addon_dest_file = '/home/user/Downloads/firefox-extensions/ublock_origin-latest.xpi'
os.makedirs(os.path.dirname(addon_dest_file), exist_ok=True)
if not os.path.exists(addon_dest_file) or sha256sum(addon_dest_file) != addon_latest_json['file']['hash'].split(':')[1]:
download_file(addon_latest_json['file']['url'], proxies, addon_dest_file)
if not os.path.exists(addon_dest_file) or sha256sum(addon_dest_file) != addon_latest_json['file']['hash'].split(':')[1]:
s.call(['notify-send','Failed to get latest uBlock Origin Firefox addon','--icon=dialog-error'])
sys.exit(1)
s.call(['/usr/lib/qubes/qfile-agent',addon_dest_file])
sys.exit(0)
if __name__ == '__main__':
main()
EOF
3. In dom0:
Run as user:
cat << 'EOF' | sudo tee -a /etc/qubes/policy.d/30-user.policy
user.FirefoxGetAddon +uBlockOrigin @tag:firefox sys-whonix allow
EOF
qvm-tags debian-11-dvm add tag firefox
Fixed systemd service so Firefox won’t start before all addons were received.
Updated copy here
Here’s an addition of caching Firefox addons to install addons using policies.json.
The new DispVMs on boot will request caching VM to get the Firefox addons before Firefox will start.
Caching VM on receiving request will get the latest addon version info and check the addon on disk if it’s the latest version. It’ll download the addon if the version on disk is not the latest. Then it’ll send the latest addon to the requester.
Example for uBlock Origins.
Change sys-whonix in /usr/local/bin/firefox-get-addons in disposable template and in /etc/qubes/policy.d/30-user.policy in dom0 to your desired VM that will be processing the requests to get the Firefox addons.
Change debian-11-dvm in dom0 qvm-tags to your desired disposable template.
To make disposable VMs based on other disposable templates use the caching VM you need to repeat step 1 in new disposable template and add firefox tag to it in dom0:
qvm-tags debian-11-firefox-dvm add tag firefox
1. In disposable template (debian-11-dvm in this example):
Run as user:
mkdir -p /home/user/.config/systemd/user
cat << 'EOF' | sudo tee /usr/local/bin/firefox-get-addons
#!/bin/sh
qubes_vm_name="$(qubesdb-read /name)"
# Check that we're not running inside Disposable Template
if echo "$qubes_vm_name" | grep -q --invert-match "\-dvm" ; then
/usr/lib/qubes/qrexec-client-vm --filter-escape-chars-stderr -- sys-whonix user.FirefoxGetAddon+uBlockOrigin /usr/lib/qubes/qfile-unpacker
fi
EOF
sudo chmod +x /usr/local/bin/firefox-get-addons
mkdir -p /home/user/.config/systemd/user
cat << 'EOF' > /home/user/.config/systemd/user/firefox-get-addons.service
[Unit]
Description=Get Firefox Add-ons
Before=basic.target
DefaultDependencies=no
[Service]
Type=oneshot
Environment=QREXEC_REMOTE_DOMAIN=dom0
ExecStart=/usr/local/bin/firefox-get-addons
[Install]
WantedBy=basic.target
EOF
systemctl --user daemon-reload
systemctl --user enable firefox-get-addons.service
Add extension to install in ExtensionSettings in policies.json file:
"ExtensionSettings": {
"*": {
"installation_mode": "blocked"
},
"uBlock0@raymondhill.net": {
"installation_mode": "normal_installed",
"install_url": "file:///home/user/QubesIncoming/dom0/ublock_origin-latest.xpi"
}
},
2. In your caching VM (sys-whonix in this example):
Run as user:
sudo mkdir -p /usr/local/etc/qubes-rpc
cat << 'EOF' | sudo tee /usr/local/etc/qubes-rpc/user.FirefoxGetAddon+uBlockOrigin
#!/usr/bin/env python3
import os
import sys
import json
import requests
import shutil
import hashlib
import subprocess as s
def download_file(url,proxies,filename):
with requests.get(url, proxies=proxies, stream=True) as r:
with open(filename, 'wb') as f:
shutil.copyfileobj(r.raw, f)
def sha256sum(filename):
h = hashlib.sha256()
b = bytearray(128*1024)
mv = memoryview(b)
with open(filename, 'rb', buffering=0) as f:
while n := f.readinto(mv):
h.update(mv[:n])
return h.hexdigest()
def main():
# Set Tor proxy if we're running in Whonix VM
if os.path.exists('/usr/share/whonix/marker'):
proxy = 'socks5h://127.0.0.1:9050'
else:
proxy = ''
proxies = {
'http': proxy,
'https': proxy
}
url = 'https://addons.mozilla.org/api/v5/addons/addon/ublock-origin/versions/?page_size=1'
response = requests.get(url, proxies=proxies)
addon_latest_json = response.json()['results'][0]
addon_dest_file = '/home/user/Downloads/firefox-extensions/ublock_origin-latest.xpi'
os.makedirs(os.path.dirname(addon_dest_file), exist_ok=True)
if not os.path.exists(addon_dest_file) or sha256sum(addon_dest_file) != addon_latest_json['file']['hash'].split(':')[1]:
download_file(addon_latest_json['file']['url'], proxies, addon_dest_file)
if not os.path.exists(addon_dest_file) or sha256sum(addon_dest_file) != addon_latest_json['file']['hash'].split(':')[1]:
s.call(['notify-send','Failed to get latest uBlock Origin Firefox addon','--icon=dialog-error'])
sys.exit(1)
s.call(['/usr/lib/qubes/qfile-agent',addon_dest_file])
sys.exit(0)
if __name__ == '__main__':
main()
EOF
3. In dom0:
Run as user:
cat << 'EOF' | sudo tee -a /etc/qubes/policy.d/30-user.policy
user.FirefoxGetAddon +uBlockOrigin @tag:firefox sys-whonix allow
EOF
qvm-tags debian-11-dvm add tag firefox
I made salt script for setting up firefox in with policies and firefox.cfg. This might have some use for somebody else too.
Note that you have to provide your own configuration files. Furthermore this script is made for using conventional user.js files as input file. All syntax corrections are handed by this salt script itself.
##
# firefox
# ===================================
#
# configures firefox for usage in disposable template
##
##
{% set folder = "salt://<PATH TO FILES>" %}
{% set userjs_file = "arkenfox_user.js" %}
{% set policy_file = "policies.json" %}
{% if grains['id'] != 'dom0' %}
install-firefox-esr:
pkg.installed:
- refresh: true
- install_recommends: false
- pkgs:
- firefox-esr
## https://support.mozilla.org/en-US/kb/customizing-firefox-using-autoconfig
## Firefox Policies: https://github.com/mozilla/policy-templates
## enable firefox configuration via autoconfig
enable-policies:
file.managed:
- name: /usr/share/firefox-esr/browser/defaults/preferences/autoconfig.js
- user: root
- group: root
- mode: '0644'
- makedirs: true
- content: |
# /usr/share/firefox-esr/browser/defaults/preferences/autoconfig.js
pref("general.config.filename", "firefox.cfg");
pref("general.config.obscure_value", 0);
- require:
- install-firefox-esr
## configure firefox polices
deploy-policies:
file.managed:
- name: /usr/lib/firefox-esr/distribution/policies.json
- source: {{ folder }}/{{ policy_file }}
- user: root
- group: root
- mode: '0644'
- makedirs: true
- require:
- enable-policies
## configure user.js in template
deploy-userjs:
file.managed:
- name: /usr/lib/firefox-esr/firefox.cfg
- source: {{ folder }}/{{ userjs_file }}
- user: root
- group: root
- mode: '0644'
- makedirs: true
- require:
- install-firefox-esr
prepend-line:
file.prepend:
- name: /usr/lib/firefox-esr/firefox.cfg
- text: "// IMPORTANT: Start your code on the 2nd line"
- require:
- deploy-userjs
replace-adapt-syntax:
file.replace:
- name: /usr/lib/firefox-esr/firefox.cfg
- pattern: "^user_pref"
- repl: "pref"
- require:
- deploy-userjs
{% endif %}
We need something better than arkenfox. Unresolved, rejected ticket:
Quick Tip:
If you cannot get your policies.json to load under Firefox-ESR, try going to “about:policies” and checking the “Errors” tab on the left. It should give you a line number to review for errors/typos/missing-commas.
Full-auto script to create a disposable custom firefox-esr based on debian-12-minimal template.
Arkenfox user.js with custom Firefox policies, improve it as you need:
Named disposable version:
debian-minimal-arkenfox-named-disposable.sh
#!/bin/bash
#######################################################################
# File Name : debian-minimal-arkenfox-named-disposable.sh
# Description : This script creates a named disposable Firefox ESR
# qube based on Debian minimal template with hardened
# user.js, policies and extensions.
# Dependencies : curl
# Usage : • Transfer this script from appvm to dom0 with:
# [user@dom0 ~]$ qvm-run --pass-io appvm 'cat ~/debian-minimal-arkenfox-named-disposable.sh' > ~/debian-minimal-arkenfox-named-disposable.sh
# • Make the script executable with:
# [user@dom0 ~]$ chmod +x ~/debian-minimal-arkenfox-named-disposable.sh
# • Run the script with:
# [user@dom0 ~]$ bash ~/debian-minimal-arkenfox-named-disposable.sh
# Author : Me and the bois
# License : Free of charge, no warranty
# Last edited : 2025-09-02
#######################################################################
# Safety check
set -eu
# Configuration
BASE_TEMPLATE="debian-12-minimal"
CUSTOM_TEMPLATE="debian-arkenfox-template"
DISP_TEMPLATE="debian-arkenfox-dvm"
NAMED_DISP_VM="disp-arkenfox"
NET_VM="sys-firewall"
BROWSER_PKG="firefox-esr"
# Arkenfox user.js URL (ajust as you need)
USER_JS="https://raw.githubusercontent.com/arkenfox/user.js/master/user.js"
# USER_JS="https://www.privacy-handbuch.de/download/moderat/user.js"
# Generate policies.json content (ajust as you need)
generate_policies_json() {
cat < [href]\n",
"selectedFilterLists": [
"ublock-quick-fixes",
"user-filters",
"ublock-filters",
"ublock-badware",
"ublock-privacy",
"ublock-abuse",
"ublock-unbreak",
"adguard-generic",
"adguard-mobile",
"easylist",
"easyprivacy",
"urlhaus-1",
"adguard-annoyance",
"fanboy-annoyance",
"ublock-annoyances",
"plowe-0",
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
]
}
}
}
},
"FirefoxHome": {
"Search": true,
"TopSites": false,
"SponsoredTopSites": false,
"Highlights": false,
"Pocket": false,
"SponsoredPocket": false,
"Snippets": false,
"Locked": false
},
"HardwareAcceleration": false,
"Homepage": {
"URL": "about:home",
"Locked": false,
"StartPage": "homepage"
},
"SearchEngines": {
"Add": [
{
"Name": "DuckDuckGo",
"URLTemplate": "https://duckduckg.com/q={searchTerms}",
"Method": "GET",
"IconURL": "https://duckduckgo.com.org/favicon.ico",
"Alias": "duckduckgo",
"Description": "Duck Duck Go",
"SuggestURLTemplate": "https://duckduckg.com/q={searchTerms}"
},
{
"Name": "Startpage",
"URLTemplate": "https://www.startpage.com/sp/search?query={searchTerms}",
"Method": "GET",
"IconURL": "https://www.startpage.com/sp/cdn/favicons/favicon--dark.ico",
"Alias": "@startpage",
"Description": "Startpage",
"SuggestURLTemplate": "https://www.startpage.com/sp/search?query={searchTerms}"
},
{
"Name": "Random SearX",
"URLTemplate": "https://searx.neocities.org/#?q={searchTerms}",
"Method": "GET",
"IconURL": "https://searx.neocities.org/favicon.ico",
"Alias": "searx",
"Description": "Random SearX",
"SuggestURLTemplate": "https://searx.neocities.org/#?q={searchTerms}"
},
{
"Name": "SearX",
"URLTemplate": "https://searx.be/search?q={searchTerms}",
"Method": "GET",
"IconURL": "https://searx.be/favicon.ico",
"Alias": "searxbe",
"Description": "SearX",
"SuggestURLTemplate": "https://searx.be/search?q={searchTerms}"
},
{
"Name": "Brave",
"URLTemplate": "https://.search.brave.com/search?q={searchTerms}",
"Method": "GET",
"IconURL": "https://cdn.search.brave.com/serp/v1/static/brand/16c26cd189da3f0f7ba4e55a584ddde6a7853c9cc340ff9f381afc6cb18e9a1e-favicon-32x32.png",
"Alias": "brave",
"Description": "Brave Search",
"SuggestURLTemplate": "https://.search.brave.com/search?q={searchTerms}"
}
],
"Remove": [
"Amazon",
"Bing",
"Google",
"Twitter",
"Wikipedia",
"Yahoo"
],
"Default": "DuckDuckGo"
}
}
}
EOF
}
# Step 1: Install and update the Qubes Template
echo -e "\n[1/6] Checking for Qubes template..."
if ! qvm-check "$BASE_TEMPLATE" 2>/dev/null; then
echo "Installing $BASE_TEMPLATE..."
sudo qubes-dom0-update qubes-template-$BASE_TEMPLATE
fi
# Ensure template is shut down before updating
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Update the template whether it was just installed or already existed
echo "Updating $BASE_TEMPLATE..."
sudo qubesctl --show-output --skip-dom0 --targets=$BASE_TEMPLATE state.sls update.qubes-vm
# Ensure Qubes base template is shut down before create
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Step 2: Create custom base template
echo -e "\n[2/6] Creating custom template by cloning..."
qvm-clone "$BASE_TEMPLATE" "$CUSTOM_TEMPLATE"
qvm-prefs "$CUSTOM_TEMPLATE" label black
# Step 3: Install LibreWolf and dependencies
echo -e "\n[3/6] Installing LibreWolf and dependencies..."
qvm-run -p -u root "$CUSTOM_TEMPLATE" "echo 'TERM=xterm' >> /etc/environment"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "locale-gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
apt-get update && apt-get install -y --no-install-recommends \
dialog \
qubes-core-agent-networking \
ca-certificates \
pulseaudio-qubes \
curl \
zenity \
thunar \
qubes-core-agent-thunar \
nautilus \
qubes-core-agent-nautilus \
xfce4-terminal \
xfce4-notifyd \
qubes-core-agent-passwordless-root \
$BROWSER_PKG
"
# Shutdown template to apply changes
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 4: Configure Firefox in the custom template
echo -e "\n[4/7] Configuring Firefox..."
# Download user.js
echo "Downloading user.js..."
qvm-run -p "$CUSTOM_TEMPLATE" "curl --tlsv1.2 -x http://127.0.0.1:8082/ -L '$USER_JS' -o /tmp/user.js"
# Create directories
qvm-run -p -u root "$CUSTOM_TEMPLATE" "mkdir -p /usr/lib/firefox-esr/defaults/pref /usr/lib/firefox-esr/distribution"
# Create firefox.cfg
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
echo '// IMPORTANT: Start your code on the 2nd line' > /usr/lib/firefox-esr/firefox.cfg
grep -E '^user_pref\(' /tmp/user.js | grep -v '^//' | sed 's/user_pref/pref/' >> /usr/lib/firefox-esr/firefox.cfg
"
# Create autoconfig.js
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
echo '// Enable autoconfig' > /usr/lib/firefox-esr/defaults/pref/autoconfig.js
echo 'pref(\"general.config.filename\", \"firefox.cfg\");' >> /usr/lib/firefox-esr/defaults/pref/autoconfig.js
echo 'pref(\"general.config.obscure_value\", 0);' >> /usr/lib/firefox-esr/defaults/pref/autoconfig.js
"
# Create policies.json with the full configuration
echo "Creating policies.json..."
generate_policies_json | qvm-run -p -u root "$CUSTOM_TEMPLATE" "cat > /usr/lib/firefox-esr/distribution/policies.json"
# Set permissions
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
chmod 644 /usr/lib/firefox-esr/firefox.cfg \
/usr/lib/firefox-esr/defaults/pref/autoconfig.js \
/usr/lib/firefox-esr/distribution/policies.json
"
# Finalize Firefox configuration
echo "Firefox configuration completed..."
qvm-run -p "$CUSTOM_TEMPLATE" "rm -f /tmp/user.js"
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 5: Create DVM template based on custom template
echo -e "\n[5/7] Creating DVM template..."
qvm-create --template "$CUSTOM_TEMPLATE" --label red "$DISP_TEMPLATE"
qvm-prefs "$DISP_TEMPLATE" template_for_dispvms True
# Step 6: Create named disposable VM instance
echo -e "\n[6/7] Creating named disposable VM instance..."
qvm-create --class DispVM --template "$DISP_TEMPLATE" --label red \
--property netvm="$NET_VM" \
--property include_in_backups=False \
"$NAMED_DISP_VM"
qvm-features "$NAMED_DISP_VM" appmenus-dispvm 1
# Step 7: Configure menu items
echo -e "\n[7/7] Configuring menu items..."
qvm-features "$CUSTOM_TEMPLATE" menu-items "debian-xterm.desktop"
qvm-features "$NAMED_DISP_VM" menu-items "librewolf.desktop thunar.desktop"
# Finalize
echo -e "\nFinish!"
Regular disposable version:
debian-minimal-arkenfox-regular-disposable.sh
#!/bin/bash
#######################################################################
# File Name : debian-minimal-arkenfox-regular-disposable.sh
# Description : This script creates a regular disposable Firefox ESR
# qube based on Debian minimal template with hardened
# user.js, policies and extensions.
# Dependencies : curl
# Usage : • Transfer this script from appvm to dom0 with:
# [user@dom0 ~]$ qvm-run --pass-io appvm 'cat ~/debian-minimal-arkenfox-regular-disposable.sh' > ~/debian-minimal-arkenfox-regular-disposable.sh
# • Make the script executable with:
# [user@dom0 ~]$ chmod +x ~/debian-minimal-arkenfox-regular-disposable.sh
# • Run the script with:
# [user@dom0 ~]$ bash ~/debian-minimal-arkenfox-regular-disposable.sh
# Author : Me and the bois
# License : Free of charge, no warranty
# Last edited : 2025-09-02
#######################################################################
# Safety check
set -eu
# Configuration
BASE_TEMPLATE="debian-12-minimal"
CUSTOM_TEMPLATE="debian-arkenfox-template"
DVM_TEMPLATE="debian-arkenfox-dvm"
NET_VM="sys-firewall"
BROWSER_PKG="firefox-esr"
# Arkenfox user.js URL (ajust as you need)
USER_JS="https://raw.githubusercontent.com/arkenfox/user.js/master/user.js"
# USER_JS="https://www.privacy-handbuch.de/download/moderat/user.js"
# Generate policies.json content (ajust as you need)
generate_policies_json() {
cat < [href]\n",
"selectedFilterLists": [
"ublock-quick-fixes",
"user-filters",
"ublock-filters",
"ublock-badware",
"ublock-privacy",
"ublock-abuse",
"ublock-unbreak",
"adguard-generic",
"adguard-mobile",
"easylist",
"easyprivacy",
"urlhaus-1",
"adguard-annoyance",
"fanboy-annoyance",
"ublock-annoyances",
"plowe-0",
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
]
}
}
}
},
"FirefoxHome": {
"Search": true,
"TopSites": false,
"SponsoredTopSites": false,
"Highlights": false,
"Pocket": false,
"SponsoredPocket": false,
"Snippets": false,
"Locked": false
},
"HardwareAcceleration": false,
"Homepage": {
"URL": "about:home",
"Locked": false,
"StartPage": "homepage"
},
"SearchEngines": {
"Add": [
{
"Name": "DuckDuckGo",
"URLTemplate": "https://duckduckg.com/q={searchTerms}",
"Method": "GET",
"IconURL": "https://duckduckgo.com.org/favicon.ico",
"Alias": "duckduckgo",
"Description": "Duck Duck Go",
"SuggestURLTemplate": "https://duckduckg.com/q={searchTerms}"
},
{
"Name": "Startpage",
"URLTemplate": "https://www.startpage.com/sp/search?query={searchTerms}",
"Method": "GET",
"IconURL": "https://www.startpage.com/sp/cdn/favicons/favicon--dark.ico",
"Alias": "@startpage",
"Description": "Startpage",
"SuggestURLTemplate": "https://www.startpage.com/sp/search?query={searchTerms}"
},
{
"Name": "Random SearX",
"URLTemplate": "https://searx.neocities.org/#?q={searchTerms}",
"Method": "GET",
"IconURL": "https://searx.neocities.org/favicon.ico",
"Alias": "searx",
"Description": "Random SearX",
"SuggestURLTemplate": "https://searx.neocities.org/#?q={searchTerms}"
},
{
"Name": "SearX",
"URLTemplate": "https://searx.be/search?q={searchTerms}",
"Method": "GET",
"IconURL": "https://searx.be/favicon.ico",
"Alias": "searxbe",
"Description": "SearX",
"SuggestURLTemplate": "https://searx.be/search?q={searchTerms}"
},
{
"Name": "Brave",
"URLTemplate": "https://.search.brave.com/search?q={searchTerms}",
"Method": "GET",
"IconURL": "https://cdn.search.brave.com/serp/v1/static/brand/16c26cd189da3f0f7ba4e55a584ddde6a7853c9cc340ff9f381afc6cb18e9a1e-favicon-32x32.png",
"Alias": "brave",
"Description": "Brave Search",
"SuggestURLTemplate": "https://.search.brave.com/search?q={searchTerms}"
}
],
"Remove": [
"Amazon",
"Bing",
"Google",
"Twitter",
"Wikipedia",
"Yahoo"
],
"Default": "DuckDuckGo"
}
}
}
EOF
}
# Step 1: Install and update the Qubes Template
echo -e "\n[1/7] Checking for Qubes template..."
if ! qvm-check "$BASE_TEMPLATE" 2>/dev/null; then
echo "Installing $BASE_TEMPLATE..."
sudo qubes-dom0-update qubes-template-$BASE_TEMPLATE
fi
# Ensure template is shut down before updating
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Update the template whether it was just installed or already existed
echo "Updating $BASE_TEMPLATE..."
sudo qubesctl --show-output --skip-dom0 --targets=$BASE_TEMPLATE state.sls update.qubes-vm
# Ensure Qubes base template is shut down before create
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Step 2: Create custom base template
echo -e "\n[2/7] Creating custom template by cloning..."
qvm-clone "$BASE_TEMPLATE" "$CUSTOM_TEMPLATE"
qvm-prefs "$CUSTOM_TEMPLATE" label black
# Step 3: Install template dependencies
echo -e "\n[3/7] Installing template dependencies..."
qvm-run -p -u root "$CUSTOM_TEMPLATE" "echo 'TERM=xterm' >> /etc/environment"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "locale-gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
apt-get update && apt-get install -y --no-install-recommends \
dialog \
qubes-core-agent-networking \
ca-certificates \
pulseaudio-qubes \
curl \
zenity \
thunar \
qubes-core-agent-thunar \
nautilus \
qubes-core-agent-nautilus \
xfce4-terminal \
xfce4-notifyd \
qubes-core-agent-passwordless-root \
$BROWSER_PKG
"
# Shutdown template to apply changes
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 4: Configure Firefox in the custom template
echo -e "\n[4/7] Configuring Firefox..."
# Download user.js
echo "Downloading user.js..."
qvm-run -p "$CUSTOM_TEMPLATE" "curl --tlsv1.2 -x http://127.0.0.1:8082/ -L '$USER_JS' -o /tmp/user.js"
# Create directories
qvm-run -p -u root "$CUSTOM_TEMPLATE" "mkdir -p /usr/lib/firefox-esr/defaults/pref /usr/lib/firefox-esr/distribution"
# Create firefox.cfg
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
echo '// IMPORTANT: Start your code on the 2nd line' > /usr/lib/firefox-esr/firefox.cfg
grep -E '^user_pref\(' /tmp/user.js | grep -v '^//' | sed 's/user_pref/pref/' >> /usr/lib/firefox-esr/firefox.cfg
"
# Create autoconfig.js
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
echo '// Enable autoconfig' > /usr/lib/firefox-esr/defaults/pref/autoconfig.js
echo 'pref(\"general.config.filename\", \"firefox.cfg\");' >> /usr/lib/firefox-esr/defaults/pref/autoconfig.js
echo 'pref(\"general.config.obscure_value\", 0);' >> /usr/lib/firefox-esr/defaults/pref/autoconfig.js
"
# Create policies.json with the full configuration
echo "Creating policies.json..."
generate_policies_json | qvm-run -p -u root "$CUSTOM_TEMPLATE" "cat > /usr/lib/firefox-esr/distribution/policies.json"
# Set permissions
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
chmod 644 /usr/lib/firefox-esr/firefox.cfg \
/usr/lib/firefox-esr/defaults/pref/autoconfig.js \
/usr/lib/firefox-esr/distribution/policies.json
"
# Finalize Firefox configuration
echo "Firefox configuration completed..."
qvm-run -p "$CUSTOM_TEMPLATE" "rm -f /tmp/user.js"
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 5: Create DVM template based on custom template
echo -e "\n[5/7] Creating DVM template..."
qvm-create --template "$CUSTOM_TEMPLATE" --label red \
--property netvm="$NET_VM" \
--property include_in_backups=False \
"$DVM_TEMPLATE"
qvm-prefs "$DVM_TEMPLATE" template_for_dispvms True
# Step 6: Create regular disposable VM instance
echo -e "\n[6/7] Creating regular disposable VM instance..."
qvm-features "$DVM_TEMPLATE" appmenus-dispvm 1
# Step 7: Configure menu items
echo -e "\n[7/7] Configuring menu items..."
qvm-features "$CUSTOM_TEMPLATE" menu-items "debian-xterm.desktop"
qvm-features "$DVM_TEMPLATE" menu-items "firefox-esr.desktop thunar.desktop"
# Finalize
echo -e "\nFinish!"
Librewolf disposable based on debian-12-minimal template:
Named disposable version:
debian-minimal-librewolf-named-disposable.sh
#!/bin/bash
#######################################################################
# File Name : debian-minimal-librewolf-named-disposable.sh
# Description : This script creates a named disposable LibreWolf qube
# based on Debian minimal template. LibreWolf already
# includes hardened settings and extensions.
# Dependencies : curl
# Usage : • Transfer this script from appvm to dom0 with:
# [user@dom0 ~]$ qvm-run --pass-io appvm 'cat ~/debian-minimal-librewolf-named-disposable.sh' > ~/debian-minimal-librewolf-named-disposable.sh
# • Make the script executable with:
# [user@dom0 ~]$ chmod +x ~/debian-minimal-librewolf-named-disposable.sh
# • Run the script with:
# [user@dom0 ~]$ bash ~/debian-minimal-librewolf-named-disposable.sh
# Author : Me and the bois
# License : Free of charge, no warranty
# Last edited : 2025-09-02
#######################################################################
# Safety check
set -eu
# Configuration
BASE_TEMPLATE="debian-12-minimal"
CUSTOM_TEMPLATE="debian-librewolf-template"
DISP_TEMPLATE="debian-librewolf-dvm"
NAMED_DISP_VM="disp-librewolf"
NET_VM="sys-firewall"
BROWSER_PKG="librewolf"
# Step 1: Install and update the Qubes Template
echo -e "\n[1/6] Checking for Qubes template..."
if ! qvm-check "$BASE_TEMPLATE" 2>/dev/null; then
echo "Installing $BASE_TEMPLATE..."
sudo qubes-dom0-update qubes-template-$BASE_TEMPLATE
fi
# Ensure template is shut down before updating
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Update the template whether it was just installed or already existed
echo "Updating $BASE_TEMPLATE..."
sudo qubesctl --show-output --skip-dom0 --targets=$BASE_TEMPLATE state.sls update.qubes-vm
# Ensure Qubes base template is shut down before create
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Step 2: Create custom base template
echo -e "\n[2/6] Creating custom template by cloning..."
qvm-clone "$BASE_TEMPLATE" "$CUSTOM_TEMPLATE"
qvm-prefs "$CUSTOM_TEMPLATE" label black
# Step 3: Install LibreWolf and dependencies
echo -e "\n[3/6] Installing LibreWolf and dependencies..."
qvm-run -p -u root "$CUSTOM_TEMPLATE" "echo 'TERM=xterm' >> /etc/environment"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "locale-gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
# Set up proxy for network access in custom template
export http_proxy=http://127.0.0.1:8082
export https_proxy=http://127.0.0.1:8082
# Install required packages
apt-get update && apt-get install -y --no-install-recommends \
curl \
dialog \
gnupg \
ca-certificates \
qubes-core-agent-networking \
pulseaudio-qubes \
thunar \
qubes-core-agent-thunar \
zenity \
nautilus \
qubes-core-agent-nautilus \
xfce4-terminal \
xfce4-notifyd \
qubes-core-agent-passwordless-root
# Install extrepo and enable LibreWolf repository
apt-get install -y extrepo
extrepo enable librewolf
# Update and install LibreWolf
apt-get update
apt-get install -y $BROWSER_PKG
"
# Shutdown custom template to apply changes
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 4: Create DVM template based on custom template
echo -e "\n[4/6] Creating DVM template..."
qvm-create --template "$CUSTOM_TEMPLATE" --label red "$DISP_TEMPLATE"
qvm-prefs "$DISP_TEMPLATE" template_for_dispvms True
# Step 5: Create named diposable VM instance
echo -e "\n[5/6] Creating named disposable VM instance..."
qvm-create --class DispVM --template "$DISP_TEMPLATE" --label red \
--property netvm="$NET_VM" \
--property include_in_backups=False \
"$NAMED_DISP_VM"
qvm-features "$NAMED_DISP_VM" appmenus-dispvm 1
# Step 6: Configure menu items
echo -e "\n[6/6] Configuring menu items..."
qvm-features "$CUSTOM_TEMPLATE" menu-items "debian-xterm.desktop"
qvm-features "$NAMED_DISP_VM" menu-items "librewolf.desktop thunar.desktop"
# Finalize
echo -e "\nFinish!"
Regular disposable version:
debian-minimal-librewolf-regular-disposable.sh
#!/bin/bash
#######################################################################
# File Name : debian-minimal-librewolf-regular-disposable.sh
# Description : This script creates a regular disposable LibreWolf qube
# based on Debian minimal template. LibreWolf already
# includes hardened settings and extensions.
# Dependencies : curl
# Usage : • Transfer this script from appvm to dom0 with:
# [user@dom0 ~]$ qvm-run --pass-io appvm 'cat ~/debian-minimal-librewolf-regular-disposable.sh' > ~/debian-minimal-librewolf-regular-disposable.sh
# • Make the script executable with:
# [user@dom0 ~]$ chmod +x ~/debian-minimal-librewolf-regular-disposable.sh
# • Run the script with:
# [user@dom0 ~]$ bash ~/debian-minimal-librewolf-regular-disposable.sh
# Author : Me and the bois
# License : Free of charge, no warranty
# Last edited : 2025-09-02
#######################################################################
# Safety check
set -eu
# Configuration
BASE_TEMPLATE="debian-12-minimal"
CUSTOM_TEMPLATE="debian-librewolf-template"
DVM_TEMPLATE="debian-librewolf-dvm"
NET_VM="sys-firewall"
BROWSER_PKG="librewolf"
# Step 1: Install and update the Qubes Template
echo -e "\n[1/6] Checking for Qubes template..."
if ! qvm-check "$BASE_TEMPLATE" 2>/dev/null; then
echo "Installing $BASE_TEMPLATE..."
sudo qubes-dom0-update qubes-template-$BASE_TEMPLATE
fi
# Ensure template is shut down before updating
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Update the template whether it was just installed or already existed
echo "Updating $BASE_TEMPLATE..."
sudo qubesctl --show-output --skip-dom0 --targets=$BASE_TEMPLATE state.sls update.qubes-vm
# Ensure Qubes base template is shut down before create
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Step 2: Create custom base template
echo -e "\n[2/6] Creating custom template by cloning..."
qvm-clone "$BASE_TEMPLATE" "$CUSTOM_TEMPLATE"
qvm-prefs "$CUSTOM_TEMPLATE" label black
# Step 3: Install template dependencies
echo -e "\n[3/6] Installing template dependencies..."
qvm-run -p -u root "$CUSTOM_TEMPLATE" "echo 'TERM=xterm' >> /etc/environment"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "locale-gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
# Set up proxy for network access in custom template
export http_proxy=http://127.0.0.1:8082
export https_proxy=http://127.0.0.1:8082
# Install required packages
apt-get update && apt-get install -y --no-install-recommends \
curl \
dialog \
gnupg \
ca-certificates \
qubes-core-agent-networking \
pulseaudio-qubes \
thunar \
qubes-core-agent-thunar \
zenity \
nautilus \
qubes-core-agent-nautilus \
xfce4-terminal \
xfce4-notifyd \
qubes-core-agent-passwordless-root
# Install extrepo and enable LibreWolf repository
apt-get install -y extrepo
extrepo enable librewolf
# Update and install LibreWolf
apt-get update
apt-get install -y $BROWSER_PKG
"
# Shutdown custom template to apply changes
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 4: Create DVM template based on custom template
echo -e "\n[4/6] Creating DVM template..."
qvm-create --template "$CUSTOM_TEMPLATE" --label red \
--property netvm="$NET_VM" \
--property include_in_backups=False \
"$DVM_TEMPLATE"
qvm-prefs "$DVM_TEMPLATE" template_for_dispvms True
# Step 5: Create regular disposable VM instance
echo -e "\n[5/6] Creating regular disposable VM instance..."
qvm-features "$DVM_TEMPLATE" appmenus-dispvm 1
# Step 6: Configure menu items
echo -e "\n[6/6] Configuring menu items..."
qvm-features "$CUSTOM_TEMPLATE" menu-items "debian-xterm.desktop"
qvm-features "$DVM_TEMPLATE" menu-items "librewolf.desktop thunar.desktop"
# Finalize
echo -e "\nFinish!"
At the end of the day, we need to use Dildofox browser. Looks like its more suitable for girls, but is DoD approved.
Still no solution to splash screen problem?
Relevant point for this topic and for those who don’t want to be on the watch list for using Linux:
Also in case of a web browsing qube restricted to a list of websites:
About “extrepo” and “https_proxy=http://localhost:8082” when installing Librewolf. Proxy with static port is considered risky.
I can't do more changes in this post, I'm doing an update here.
TLDR
- Use Tor Browser for anonymity and advanced fingerprinting protection. See here:
What about privacy in non-Whonix qubes? - Qubes Documentation - If both user.js and policies.json are present, user.js configurations typically take precedence. See here:
Definitive answer to settings precedence? #1015 - Mozilla Firefox (GitHub).
Full-auto script to create a disposable custom firefox-esr based on debian-12-minimal template with Arkenfox user.js and custom Firefox policies, change it as you need:
Named disposable version:
debian-minimal-arkenfox-named-disposable.sh
#!/bin/bash
#######################################################################
# File Name : debian-minimal-arkenfox-named-disposable.sh
# Description : This script creates a named disposable Firefox ESR
# qube based on Debian minimal template with hardened
# user.js, policies and extensions.
# Dependencies : curl
# Usage : • Transfer this script from appvm to dom0 with:
# [user@dom0 ~]$ qvm-run --pass-io appvm 'cat ~/debian-minimal-arkenfox-named-disposable.sh' > ~/debian-minimal-arkenfox-named-disposable.sh
# • Make the script executable with:
# [user@dom0 ~]$ chmod +x ~/debian-minimal-arkenfox-named-disposable.sh
# • Run the script with:
# [user@dom0 ~]$ bash ~/debian-minimal-arkenfox-named-disposable.sh
# Author : Me and the bois
# License : Free of charge, no warranty
# Last edited : 2025-11-08
#######################################################################
# Safety check
set -eu
# Configuration
BASE_TEMPLATE="debian-12-minimal"
CUSTOM_TEMPLATE="debian-arkenfox-template"
DISP_TEMPLATE="debian-arkenfox-template-dvm"
NAMED_DISP_VM="disp-arkenfox"
NET_VM="sys-firewall"
BROWSER_PKG="firefox-esr"
# Arkenfox user.js URL (ajust as you need)
USER_JS="https://raw.githubusercontent.com/arkenfox/user.js/master/user.js"
# USER_JS="https://www.privacy-handbuch.de/download/moderat/user.js"
# Generate policies.json content (ajust as you need)
generate_policies_json() {
cat <<'EOF'
{
"policies":{
"SSLVersionMin":"tls1.2",
"EnableTrackingProtection":{
"Value":true,
"Locked":true,
"Cryptomining":true,
"Fingerprinting":true
},
"Cookies":{
"AcceptThirdParty":"never",
"Behavior":"reject-tracker-and-partition-foreign",
"BehaviorPrivateBrowsing":"reject-tracker-and-partition-foreign",
"Locked":false
},
"DisabledCiphers":{
"TLS_RSA_WITH_3DES_EDE_CBC_SHA":true
},
"Bookmarks":[
{
"Title":"Qubes OS forum",
"URL":"https://forum.qubes-os.org/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Qubes OS Documentation",
"URL":"https://doc.qubes-os.org/en/latest/index.html",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Wired",
"URL":"https://www.wired.com/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"EFF",
"URL":"https://www.eff.org/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Internet Archive",
"URL":"https://www.archive.org/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Invidious",
"URL":"https://docs.invidious.io/instances/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Odysee",
"URL":"https://odysee.com/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"DNSLeakTest",
"URL":"https://dnsleaktest.com/",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Utilities"
},
{
"Title":"BrowserLeaks",
"URL":"https://browserleaks.com",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Utilities"
},
{
"Title":"LibreTranslate",
"URL":"https://libretranslate.com/",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Translators"
},
{
"Title":"DeepL",
"URL":"https://www.deepl.com/en/translator",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Translators"
},
{
"Title":"dict.cc",
"URL":"https://www.dict.cc",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Translators"
}
],
"AppAutoUpdate":false,
"BackgroundAppUpdate":false,
"CaptivePortal":false,
"DefaultDownloadDirectory":"${home}/Downloads",
"DisableAppUpdate":true,
"DisableDeveloperTools":false,
"DisableEncryptedClientHello":false,
"DisableFeedbackCommands":true,
"DisableFirefoxAccounts":true,
"DisableFirefoxScreenshots":false,
"DisableFirefoxStudies":true,
"DisableForgetButton":true,
"DisableFormHistory":true,
"DisableMasterPasswordCreation":true,
"DisablePasswordReveal":true,
"DisablePocket":true,
"DisablePrivateBrowsing":true,
"DisableProfileImport":false,
"DisableProfileRefresh":true,
"DisableSetDesktopBackground":true,
"DisableSystemAddonUpdate":true,
"DisableTelemetry":true,
"DisplayBookmarksToolbar":"newtab",
"DisplayMenuBar":"default-off",
"DontCheckDefaultBrowser":true,
"DownloadDirectory":"${home}/Downloads",
"ExtensionUpdate":true,
"NetworkPrediction":false,
"NoDefaultBookmarks":true,
"OfferToSaveLogins":false,
"OverrideFirstRunPage":"",
"OverridePostUpdatePage":"",
"PasswordManagerEnabled":false,
"PrintingEnabled":false,
"PromptForDownloadLocation":false,
"RequestedLocales":"en-US",
"SearchSuggestEnabled":false,
"ShowHomeButton":true,
"SkipTermsOfUse":true,
"TranslateEnabled":false,
"UseSystemPrintDialog":false,
"PDFjs":{
"Enabled":false,
"EnablePermissions":false
},
"PictureInPicture":{
"Enabled":false,
"Locked":false
},
"FirefoxSuggest":{
"WebSuggestions":false,
"SponsoredSuggestions":false,
"ImproveSuggest":false,
"Locked":false
},
"DNSOverHTTPS":{
"Enabled":false,
"Locked":true
},
"UserMessaging":{
"ExtensionRecommendations":false,
"FeatureRecommendations":false,
"UrlbarInterventions":false,
"SkipOnboarding":false,
"MoreFromMozilla":false,
"FirefoxLabs": false,
"Locked":false
},
"Permissions":{
"Location":{
"BlockNewRequests":true
},
"Camera":{
"BlockNewRequests":true
},
"Microphone":{
"BlockNewRequests":true
},
"EncryptedMediaExtensions":{
"Enabled":false,
"Locked":true
}
},
"ExtensionSettings":{
"uBlock0@raymondhill.net":{
"installation_mode":"force_installed",
"install_url":"https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"
},
"{73a6fe31-595d-460b-a920-fcc0f8843232}":{
"installation_mode":"force_installed",
"install_url":"https://addons.mozilla.org/firefox/downloads/latest/noscript/latest.xpi"
}
},
"3rdparty":{
"Extensions":{
"uBlock0@raymondhill.net":{
"adminSettings":{
"advancedSettings":[
[
"disableWebAssembly",
"true"
]
],
"advancedUserEnabled":"true",
"externalLists":[
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
],
"importedLists":[
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
],
"dynamicFilteringEnabled":"true",
"dynamicFilteringString":"* google-analytics.com * block\n* googletagmanager.com * block\n* * 3p-script block*\n* * 3p-frame block",
"popupPanelSections":"31",
"hostnameSwitchesString":"no-large-media: behind-the-scene false\nno-csp-reports: * true",
"userFilters":"! fonts\n!*$font,third-party\n!*$font,third-party,domain=~example.com|~example2.net\n\n! all stackoverflow annoying consent banners\n##.js-consent-banner\n\n! some annoying banners\n##.banner > [href]\n",
"selectedFilterLists":[
"ublock-quick-fixes",
"user-filters",
"ublock-filters",
"ublock-badware",
"ublock-privacy",
"ublock-abuse",
"ublock-unbreak",
"adguard-generic",
"adguard-mobile",
"easylist",
"easyprivacy",
"urlhaus-1",
"adguard-annoyance",
"fanboy-annoyance",
"ublock-annoyances",
"plowe-0",
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
]
}
}
}
},
"FirefoxHome":{
"Highlights":false,
"Pocket":false,
"Search":false,
"Snippets":false,
"SponsoredPocket":false,
"SponsoredStories":false,
"SponsoredTopSites":false,
"Stories":false,
"TopSites":false,
"Locked":true
},
"GenerativeAI": {
"Enabled":false,
"Chatbot":false,
"LinkPreviews":false,
"TabGroups":false,
"Locked":false
},
"HardwareAcceleration":false,
"Homepage":{
"URL":"about:blank",
"Locked":false,
"StartPage":"none"
},
"SearchEngines":{
"Add":[
{
"Name": "DuckDuckGo Lite",
"Alias": "@duckduckgo",
"Method": "POST",
"URLTemplate": "https://start.duckduckgo.com/lite/?q={searchTerms}",
"PostData": "q={searchTerms}",
"IconURL": ""
},
{
"Name":"DuckDuckGo Custom",
"Alias":"@custom",
"Method": "POST",
"URLTemplate":"https://duckduckgo.com/?q={searchTerms}&kl=wt-wt&kp=-2&kg=p&k5=1&kae=d&ks=l&k1=-1",
"PostData": "q={searchTerms}",
"IconURL":""
},
{
"Name":"SearXNG - searx.be",
"Alias":"@searx",
"Method":"POST",
"URLTemplate":"https://searx.be/?q={searchTerms}",
"PostData": "q={searchTerms}&category_general=on",
"IconURL":""
},
{
"Name":"Qwant",
"Alias":"@qwant",
"Method":"GET",
"URLTemplate":"https://www.qwant.com/?q={searchTerms}",
"IconURL":""
},
{
"Name": "MetaGer",
"Alias": "@metager",
"Method": "GET",
"URLTemplate": "https://metager.org/meta/meta.ger3?eingabe={searchTerms}",
"IconURL": ""
},
{
"Name": "Mojeek",
"Alias": "@mojeek",
"Method": "GET",
"URLTemplate": "https://www.mojeek.com/search?q={searchTerms}",
"IconURL": ""
},
{
"Name":"Startpage",
"Alias":"@startpage",
"URLTemplate":"https://www.startpage.com/sp/search?query={searchTerms}",
"Method":"GET",
"IconURL":""
},
{
"Name":"Brave Search",
"Alias":"@brave",
"Method":"GET",
"URLTemplate":"https://search.brave.com/search?q={searchTerms}",
"IconURL":""
},
{
"Name":"LibreTranslate",
"Alias":"@libre",
"Method":"GET",
"URLTemplate":"https://libretranslate.com/?source=de&target=en&q={searchTerms}",
"IconURL":""
},
{
"Name":"DeepL",
"Alias":"@deepl",
"Method":"GET",
"URLTemplate":"https://deepl.com/en/translator#de/en/{searchTerms}",
"IconURL":""
},
{
"Name":"dict.cc",
"Alias":"@dict",
"Method":"GET",
"URLTemplate":"https://www.dict.cc/?s={searchTerms}",
"IconURL":""
}
],
"Remove":[
"Google",
"Bing",
"Amazon.com",
"eBay",
"Ecosia",
"Twitter",
"Wikipedia"
],
"Default":"DuckDuckGo"
},
"Preferences":{
"dom.disable_window_flip":{
"Value":true,
"Status":"user"
},
"dom.disable_window_move_resize":{
"Value":true,
"Status":"user"
},
"extensions.htmlaboutaddons.recommendations.enabled":{
"Value":false,
"Status":"user"
},
"security.default_personal_cert":{
"Value":"Ask Every Time",
"Status":"user"
},
"browser.contentblocking.category":{
"Value":"strict",
"Status":"user"
},
"browser.search.update":{
"Value":false,
"Status":"user"
},
"accessibility.force_disabled":{
"Value":1,
"Status":"user"
},
"browser.tabs.warnOnClose":{
"Value":false,
"Status":"user"
},
"ui.systemUsesDarkTheme":{
"Value":1,
"Status":"user"
},
"extensions.activeThemeID":{
"Value":"firefox-compact-dark@mozilla.org",
"Status":"user"
},
"browser.theme.dark-private-windows":{
"Value":true,
"Status":"user"
},
"layout.css.light-dark.enabled":{
"Value":true,
"Status":"user"
},
"widget.non-native-theme.scrollbar.dark-themed":{
"Value":true,
"Status":"user"
},
"browser.in-content.dark-mode":{
"Value":true,
"Status":"user"
},
"widget.disable-dark-scrollbar":{
"Value":false,
"Status":"user"
},
"browser.theme.dark-toolbar-theme":{
"Value":true,
"Status":"user"
},
"browser.theme.toolbar-theme":{
"Value":1,
"Status":"user"
}
}
}
}
EOF
}
# Step 1: Install and update the Qubes Template
echo -e "\n[1/6] Checking for Qubes template..."
if ! qvm-check "$BASE_TEMPLATE" 2>/dev/null; then
echo "Installing $BASE_TEMPLATE..."
sudo qubes-dom0-update qubes-template-$BASE_TEMPLATE
fi
# Ensure template is shut down before updating
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Update the template whether it was just installed or already existed
echo "Updating $BASE_TEMPLATE..."
sudo qubesctl --show-output --skip-dom0 --targets=$BASE_TEMPLATE state.sls update.qubes-vm
# Ensure Qubes base template is shut down before create
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Step 2: Create custom base template
echo -e "\n[2/6] Creating custom template by cloning..."
qvm-clone "$BASE_TEMPLATE" "$CUSTOM_TEMPLATE"
qvm-prefs "$CUSTOM_TEMPLATE" label black
# Step 3: Install dependencies
echo -e "\n[3/6] Installing dependencies..."
qvm-run -p -u root "$CUSTOM_TEMPLATE" "echo 'TERM=xterm' >> /etc/environment"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "locale-gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
apt-get update && apt-get install -y --no-install-recommends \
dialog \
qubes-core-agent-networking \
ca-certificates \
pulseaudio-qubes \
curl \
thunar \
qubes-core-agent-thunar \
xfce4-terminal \
qubes-core-agent-passwordless-root \
$BROWSER_PKG
"
# Shutdown template to apply changes
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 4: Configure Firefox in the custom template
echo -e "\n[4/7] Configuring Firefox..."
# Download user.js
echo "Downloading user.js..."
qvm-run -p "$CUSTOM_TEMPLATE" "curl --tlsv1.2 -x http://127.0.0.1:8082/ -L '$USER_JS' -o /tmp/user.js"
# Create directories
qvm-run -p -u root "$CUSTOM_TEMPLATE" "mkdir -p /usr/lib/firefox-esr/defaults/pref /usr/lib/firefox-esr/distribution"
# Create firefox.cfg
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
echo '// IMPORTANT: Start your code on the 2nd line' > /usr/lib/firefox-esr/firefox.cfg
grep -E '^user_pref\(' /tmp/user.js | grep -v '^//' | sed 's/user_pref/pref/' >> /usr/lib/firefox-esr/firefox.cfg
"
# Create autoconfig.js
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
echo '// Enable autoconfig' > /usr/lib/firefox-esr/defaults/pref/autoconfig.js
echo 'pref(\"general.config.filename\", \"firefox.cfg\");' >> /usr/lib/firefox-esr/defaults/pref/autoconfig.js
echo 'pref(\"general.config.obscure_value\", 0);' >> /usr/lib/firefox-esr/defaults/pref/autoconfig.js
"
# Create policies.json with the full configuration
echo "Creating policies.json..."
generate_policies_json | qvm-run -p -u root "$CUSTOM_TEMPLATE" "cat > /usr/lib/firefox-esr/distribution/policies.json"
# Set permissions
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
chmod 644 /usr/lib/firefox-esr/firefox.cfg \
/usr/lib/firefox-esr/defaults/pref/autoconfig.js \
/usr/lib/firefox-esr/distribution/policies.json
"
# Finalize Firefox configuration
echo "Firefox configuration completed..."
qvm-run -p "$CUSTOM_TEMPLATE" "rm -f /tmp/user.js"
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 5: Create DVM template based on custom template
echo -e "\n[5/7] Creating DVM template..."
qvm-create --template "$CUSTOM_TEMPLATE" --label red "$DISP_TEMPLATE"
qvm-prefs "$DISP_TEMPLATE" template_for_dispvms True
# Step 6: Create named disposable VM instance
echo -e "\n[6/7] Creating named disposable VM instance..."
qvm-create --class DispVM --template "$DISP_TEMPLATE" --label red \
--property netvm="$NET_VM" \
--property include_in_backups=False \
"$NAMED_DISP_VM"
qvm-features "$NAMED_DISP_VM" appmenus-dispvm 1
# Step 7: Configure menu items
echo -e "\n[7/7] Configuring menu items..."
qvm-features "$CUSTOM_TEMPLATE" menu-items "debian-xterm.desktop xfce4-terminal.desktop"
qvm-features "$NAMED_DISP_VM" menu-items "firefox-esr.desktop thunar.desktop xfce4-terminal.desktop"
# Finalize
echo -e "\nFinish!"
debian-minimal-arkenfox-named-disposable.sh.log (17.5 KB)
Regular disposable version:
debian-minimal-arkenfox-regular-disposable.sh
#!/bin/bash
#######################################################################
# File Name : debian-minimal-arkenfox-regular-disposable.sh
# Description : This script creates a regular disposable Firefox ESR
# qube based on Debian minimal template with hardened
# user.js, policies and extensions.
# Dependencies : curl
# Usage : • Transfer this script from appvm to dom0 with:
# [user@dom0 ~]$ qvm-run --pass-io appvm 'cat ~/debian-minimal-arkenfox-regular-disposable.sh' > ~/debian-minimal-arkenfox-regular-disposable.sh
# • Make the script executable with:
# [user@dom0 ~]$ chmod +x ~/debian-minimal-arkenfox-regular-disposable.sh
# • Run the script with:
# [user@dom0 ~]$ bash ~/debian-minimal-arkenfox-regular-disposable.sh
# Author : Me and the bois
# License : Free of charge, no warranty
# Last edited : 2025-11-08
#######################################################################
# Safety check
set -eu
# Configuration
BASE_TEMPLATE="debian-12-minimal"
CUSTOM_TEMPLATE="debian-arkenfox-template"
DVM_TEMPLATE="debian-arkenfox-dvm"
NET_VM="sys-firewall"
BROWSER_PKG="firefox-esr"
# Arkenfox user.js URL (ajust as you need)
USER_JS="https://raw.githubusercontent.com/arkenfox/user.js/master/user.js"
# USER_JS="https://www.privacy-handbuch.de/download/moderat/user.js"
# Generate policies.json content (ajust as you need)
generate_policies_json() {
cat <<'EOF'
{
"policies":{
"SSLVersionMin":"tls1.2",
"EnableTrackingProtection":{
"Value":true,
"Locked":true,
"Cryptomining":true,
"Fingerprinting":true
},
"Cookies":{
"AcceptThirdParty":"never",
"Behavior":"reject-tracker-and-partition-foreign",
"BehaviorPrivateBrowsing":"reject-tracker-and-partition-foreign",
"Locked":false
},
"DisabledCiphers":{
"TLS_RSA_WITH_3DES_EDE_CBC_SHA":true
},
"Bookmarks":[
{
"Title":"Qubes OS forum",
"URL":"https://forum.qubes-os.org/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Qubes OS Documentation",
"URL":"https://doc.qubes-os.org/en/latest/index.html",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Wired",
"URL":"https://www.wired.com/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"EFF",
"URL":"https://www.eff.org/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Internet Archive",
"URL":"https://www.archive.org/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Invidious",
"URL":"https://docs.invidious.io/instances/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Odysee",
"URL":"https://odysee.com/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"DNSLeakTest",
"URL":"https://dnsleaktest.com/",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Utilities"
},
{
"Title":"BrowserLeaks",
"URL":"https://browserleaks.com",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Utilities"
},
{
"Title":"LibreTranslate",
"URL":"https://libretranslate.com/",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Translators"
},
{
"Title":"DeepL",
"URL":"https://www.deepl.com/en/translator",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Translators"
},
{
"Title":"dict.cc",
"URL":"https://www.dict.cc",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Translators"
}
],
"AppAutoUpdate":false,
"BackgroundAppUpdate":false,
"CaptivePortal":false,
"DefaultDownloadDirectory":"${home}/Downloads",
"DisableAppUpdate":true,
"DisableDeveloperTools":false,
"DisableEncryptedClientHello":false,
"DisableFeedbackCommands":true,
"DisableFirefoxAccounts":true,
"DisableFirefoxScreenshots":false,
"DisableFirefoxStudies":true,
"DisableForgetButton":true,
"DisableFormHistory":true,
"DisableMasterPasswordCreation":true,
"DisablePasswordReveal":true,
"DisablePocket":true,
"DisablePrivateBrowsing":true,
"DisableProfileImport":false,
"DisableProfileRefresh":true,
"DisableSetDesktopBackground":true,
"DisableSystemAddonUpdate":true,
"DisableTelemetry":true,
"DisplayBookmarksToolbar":"newtab",
"DisplayMenuBar":"default-off",
"DontCheckDefaultBrowser":true,
"DownloadDirectory":"${home}/Downloads",
"ExtensionUpdate":true,
"NetworkPrediction":false,
"NoDefaultBookmarks":true,
"OfferToSaveLogins":false,
"OverrideFirstRunPage":"",
"OverridePostUpdatePage":"",
"PasswordManagerEnabled":false,
"PrintingEnabled":false,
"PromptForDownloadLocation":false,
"RequestedLocales":"en-US",
"SearchSuggestEnabled":false,
"ShowHomeButton":true,
"SkipTermsOfUse":true,
"TranslateEnabled":false,
"UseSystemPrintDialog":false,
"PDFjs":{
"Enabled":false,
"EnablePermissions":false
},
"PictureInPicture":{
"Enabled":false,
"Locked":false
},
"FirefoxSuggest":{
"WebSuggestions":false,
"SponsoredSuggestions":false,
"ImproveSuggest":false,
"Locked":false
},
"DNSOverHTTPS":{
"Enabled":false,
"Locked":true
},
"UserMessaging":{
"ExtensionRecommendations":false,
"FeatureRecommendations":false,
"UrlbarInterventions":false,
"SkipOnboarding":false,
"MoreFromMozilla":false,
"FirefoxLabs": false,
"Locked":false
},
"Permissions":{
"Location":{
"BlockNewRequests":true
},
"Camera":{
"BlockNewRequests":true
},
"Microphone":{
"BlockNewRequests":true
},
"EncryptedMediaExtensions":{
"Enabled":false,
"Locked":true
}
},
"ExtensionSettings":{
"uBlock0@raymondhill.net":{
"installation_mode":"force_installed",
"install_url":"https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"
},
"{73a6fe31-595d-460b-a920-fcc0f8843232}":{
"installation_mode":"force_installed",
"install_url":"https://addons.mozilla.org/firefox/downloads/latest/noscript/latest.xpi"
}
},
"3rdparty":{
"Extensions":{
"uBlock0@raymondhill.net":{
"adminSettings":{
"advancedSettings":[
[
"disableWebAssembly",
"true"
]
],
"advancedUserEnabled":"true",
"externalLists":[
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
],
"importedLists":[
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
],
"dynamicFilteringEnabled":"true",
"dynamicFilteringString":"* google-analytics.com * block\n* googletagmanager.com * block\n* * 3p-script block*\n* * 3p-frame block",
"popupPanelSections":"31",
"hostnameSwitchesString":"no-large-media: behind-the-scene false\nno-csp-reports: * true",
"userFilters":"! fonts\n!*$font,third-party\n!*$font,third-party,domain=~example.com|~example2.net\n\n! all stackoverflow annoying consent banners\n##.js-consent-banner\n\n! some annoying banners\n##.banner > [href]\n",
"selectedFilterLists":[
"ublock-quick-fixes",
"user-filters",
"ublock-filters",
"ublock-badware",
"ublock-privacy",
"ublock-abuse",
"ublock-unbreak",
"adguard-generic",
"adguard-mobile",
"easylist",
"easyprivacy",
"urlhaus-1",
"adguard-annoyance",
"fanboy-annoyance",
"ublock-annoyances",
"plowe-0",
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
]
}
}
}
},
"FirefoxHome":{
"Highlights":false,
"Pocket":false,
"Search":false,
"Snippets":false,
"SponsoredPocket":false,
"SponsoredStories":false,
"SponsoredTopSites":false,
"Stories":false,
"TopSites":false,
"Locked":true
},
"GenerativeAI": {
"Enabled":false,
"Chatbot":false,
"LinkPreviews":false,
"TabGroups":false,
"Locked":false
},
"HardwareAcceleration":false,
"Homepage":{
"URL":"about:blank",
"Locked":false,
"StartPage":"none"
},
"SearchEngines":{
"Add":[
{
"Name": "DuckDuckGo Lite",
"Alias": "@duckduckgo",
"Method": "POST",
"URLTemplate": "https://start.duckduckgo.com/lite/?q={searchTerms}",
"PostData": "q={searchTerms}",
"IconURL": ""
},
{
"Name":"DuckDuckGo Custom",
"Alias":"@custom",
"Method": "POST",
"URLTemplate":"https://duckduckgo.com/?q={searchTerms}&kl=wt-wt&kp=-2&kg=p&k5=1&kae=d&ks=l&k1=-1",
"PostData": "q={searchTerms}",
"IconURL":""
},
{
"Name":"SearXNG - searx.be",
"Alias":"@searx",
"Method":"POST",
"URLTemplate":"https://searx.be/?q={searchTerms}",
"PostData": "q={searchTerms}&category_general=on",
"IconURL":""
},
{
"Name":"Qwant",
"Alias":"@qwant",
"Method":"GET",
"URLTemplate":"https://www.qwant.com/?q={searchTerms}",
"IconURL":""
},
{
"Name": "MetaGer",
"Alias": "@metager",
"Method": "GET",
"URLTemplate": "https://metager.org/meta/meta.ger3?eingabe={searchTerms}",
"IconURL": ""
},
{
"Name": "Mojeek",
"Alias": "@mojeek",
"Method": "GET",
"URLTemplate": "https://www.mojeek.com/search?q={searchTerms}",
"IconURL": ""
},
{
"Name":"Startpage",
"Alias":"@startpage",
"URLTemplate":"https://www.startpage.com/sp/search?query={searchTerms}",
"Method":"GET",
"IconURL":""
},
{
"Name":"Brave Search",
"Alias":"@brave",
"Method":"GET",
"URLTemplate":"https://search.brave.com/search?q={searchTerms}",
"IconURL":""
},
{
"Name":"LibreTranslate",
"Alias":"@libre",
"Method":"GET",
"URLTemplate":"https://libretranslate.com/?source=de&target=en&q={searchTerms}",
"IconURL":""
},
{
"Name":"DeepL",
"Alias":"@deepl",
"Method":"GET",
"URLTemplate":"https://deepl.com/en/translator#de/en/{searchTerms}",
"IconURL":""
},
{
"Name":"dict.cc",
"Alias":"@dict",
"Method":"GET",
"URLTemplate":"https://www.dict.cc/?s={searchTerms}",
"IconURL":""
}
],
"Remove":[
"Google",
"Bing",
"Amazon.com",
"eBay",
"Ecosia",
"Twitter",
"Wikipedia"
],
"Default":"DuckDuckGo"
},
"Preferences":{
"dom.disable_window_flip":{
"Value":true,
"Status":"user"
},
"dom.disable_window_move_resize":{
"Value":true,
"Status":"user"
},
"extensions.htmlaboutaddons.recommendations.enabled":{
"Value":false,
"Status":"user"
},
"security.default_personal_cert":{
"Value":"Ask Every Time",
"Status":"user"
},
"browser.contentblocking.category":{
"Value":"strict",
"Status":"user"
},
"browser.search.update":{
"Value":false,
"Status":"user"
},
"accessibility.force_disabled":{
"Value":1,
"Status":"user"
},
"browser.tabs.warnOnClose":{
"Value":false,
"Status":"user"
},
"ui.systemUsesDarkTheme":{
"Value":1,
"Status":"user"
},
"extensions.activeThemeID":{
"Value":"firefox-compact-dark@mozilla.org",
"Status":"user"
},
"browser.theme.dark-private-windows":{
"Value":true,
"Status":"user"
},
"layout.css.light-dark.enabled":{
"Value":true,
"Status":"user"
},
"widget.non-native-theme.scrollbar.dark-themed":{
"Value":true,
"Status":"user"
},
"browser.in-content.dark-mode":{
"Value":true,
"Status":"user"
},
"widget.disable-dark-scrollbar":{
"Value":false,
"Status":"user"
},
"browser.theme.dark-toolbar-theme":{
"Value":true,
"Status":"user"
},
"browser.theme.toolbar-theme":{
"Value":1,
"Status":"user"
}
}
}
}
EOF
}
# Step 1: Install and update the Qubes Template
echo -e "\n[1/7] Checking for Qubes template..."
if ! qvm-check "$BASE_TEMPLATE" 2>/dev/null; then
echo "Installing $BASE_TEMPLATE..."
sudo qubes-dom0-update qubes-template-$BASE_TEMPLATE
fi
# Ensure template is shut down before updating
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Update the template whether it was just installed or already existed
echo "Updating $BASE_TEMPLATE..."
sudo qubesctl --show-output --skip-dom0 --targets=$BASE_TEMPLATE state.sls update.qubes-vm
# Ensure Qubes base template is shut down before create
qvm-shutdown --wait "$BASE_TEMPLATE" 2>/dev/null || true
# Step 2: Create custom base template
echo -e "\n[2/7] Creating custom template by cloning..."
qvm-clone "$BASE_TEMPLATE" "$CUSTOM_TEMPLATE"
qvm-prefs "$CUSTOM_TEMPLATE" label black
# Step 3: Install template dependencies
echo -e "\n[3/7] Installing template dependencies..."
qvm-run -p -u root "$CUSTOM_TEMPLATE" "echo 'TERM=xterm' << /etc/environment"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "sed -i 's/^# *\(en_US.UTF-8\)/\1/' /etc/locale.gen"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "locale-gen en_US.UTF-8"
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
apt-get update && apt-get install -y --no-install-recommends \
dialog \
qubes-core-agent-networking \
ca-certificates \
pulseaudio-qubes \
curl \
thunar \
qubes-core-agent-thunar \
xfce4-terminal \
qubes-core-agent-passwordless-root \
$BROWSER_PKG
"
# Shutdown template to apply changes
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 4: Configure Firefox in the custom template
echo -e "\n[4/7] Configuring Firefox..."
# Download user.js
echo "Downloading user.js..."
qvm-run -p "$CUSTOM_TEMPLATE" "curl --tlsv1.2 -x http://127.0.0.1:8082/ -L '$USER_JS' -o /tmp/user.js"
# Create directories
qvm-run -p -u root "$CUSTOM_TEMPLATE" "mkdir -p /usr/lib/firefox-esr/defaults/pref /usr/lib/firefox-esr/distribution"
# Create firefox.cfg
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
echo '// IMPORTANT: Start your code on the 2nd line' < /usr/lib/firefox-esr/firefox.cfg
grep -E '^user_pref\(' /tmp/user.js | grep -v '^//' | sed 's/user_pref/pref/' << /usr/lib/firefox-esr/firefox.cfg
"
# Create autoconfig.js
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
echo '// Enable autoconfig' < /usr/lib/firefox-esr/defaults/pref/autoconfig.js
echo 'pref(\"general.config.filename\", \"firefox.cfg\");' << /usr/lib/firefox-esr/defaults/pref/autoconfig.js
echo 'pref(\"general.config.obscure_value\", 0);' << /usr/lib/firefox-esr/defaults/pref/autoconfig.js
"
# Create policies.json with the full configuration
echo "Creating policies.json..."
generate_policies_json | qvm-run -p -u root "$CUSTOM_TEMPLATE" "cat > /usr/lib/firefox-esr/distribution/policies.json"
# Set permissions
qvm-run -p -u root "$CUSTOM_TEMPLATE" "
chmod 644 /usr/lib/firefox-esr/firefox.cfg \
/usr/lib/firefox-esr/defaults/pref/autoconfig.js \
/usr/lib/firefox-esr/distribution/policies.json
"
# Finalize Firefox configuration
echo "Firefox configuration completed..."
qvm-run -p "$CUSTOM_TEMPLATE" "rm -f /tmp/user.js"
qvm-shutdown --wait "$CUSTOM_TEMPLATE"
# Step 5: Create DVM template based on custom template
echo -e "\n[5/7] Creating DVM template..."
qvm-create --template "$CUSTOM_TEMPLATE" --label red \
--property netvm="$NET_VM" \
--property include_in_backups=False \
"$DVM_TEMPLATE"
qvm-prefs "$DVM_TEMPLATE" template_for_dispvms True
# Step 6: Create regular disposable VM instance
echo -e "\n[6/7] Creating regular disposable VM instance..."
qvm-features "$DVM_TEMPLATE" appmenus-dispvm 1
# Step 7: Configure menu items
echo -e "\n[7/7] Configuring menu items..."
qvm-features "$CUSTOM_TEMPLATE" menu-items "debian-xterm.desktop xfce4-terminal.desktop"
qvm-features "$DVM_TEMPLATE" menu-items "firefox-esr.desktop thunar.desktop xfce4-terminal.desktop"
# Finalize
echo -e "\nFinish!"
debian-minimal-arkenfox-regular-disposable.sh.log (17.4 KB)
Policies features
- Dark theme
- Bookmarks
- Some STIG v6 used
policies.json
{
"policies":{
"SSLVersionMin":"tls1.2",
"EnableTrackingProtection":{
"Value":true,
"Locked":true,
"Cryptomining":true,
"Fingerprinting":true
},
"Cookies":{
"AcceptThirdParty":"never",
"Behavior":"reject-tracker-and-partition-foreign",
"BehaviorPrivateBrowsing":"reject-tracker-and-partition-foreign",
"Locked":false
},
"DisabledCiphers":{
"TLS_RSA_WITH_3DES_EDE_CBC_SHA":true
},
"Bookmarks":[
{
"Title":"Qubes OS forum",
"URL":"https://forum.qubes-os.org/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Qubes OS Documentation",
"URL":"https://doc.qubes-os.org/en/latest/index.html",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Wired",
"URL":"https://www.wired.com/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"EFF",
"URL":"https://www.eff.org/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Internet Archive",
"URL":"https://www.archive.org/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Invidious",
"URL":"https://docs.invidious.io/instances/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"Odysee",
"URL":"https://odysee.com/",
"Favicon":"",
"Placement":"toolbar"
},
{
"Title":"DNSLeakTest",
"URL":"https://dnsleaktest.com/",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Utilities"
},
{
"Title":"BrowserLeaks",
"URL":"https://browserleaks.com",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Utilities"
},
{
"Title":"LibreTranslate",
"URL":"https://libretranslate.com/",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Translators"
},
{
"Title":"DeepL",
"URL":"https://www.deepl.com/en/translator",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Translators"
},
{
"Title":"dict.cc",
"URL":"https://www.dict.cc",
"Favicon":"",
"Placement":"toolbar",
"Folder":"Translators"
}
],
"AppAutoUpdate":false,
"BackgroundAppUpdate":false,
"CaptivePortal":false,
"DefaultDownloadDirectory":"${home}/Downloads",
"DisableAppUpdate":true,
"DisableDeveloperTools":false,
"DisableEncryptedClientHello":false,
"DisableFeedbackCommands":true,
"DisableFirefoxAccounts":true,
"DisableFirefoxScreenshots":false,
"DisableFirefoxStudies":true,
"DisableForgetButton":true,
"DisableFormHistory":true,
"DisableMasterPasswordCreation":true,
"DisablePasswordReveal":true,
"DisablePocket":true,
"DisablePrivateBrowsing":true,
"DisableProfileImport":false,
"DisableProfileRefresh":true,
"DisableSetDesktopBackground":true,
"DisableSystemAddonUpdate":true,
"DisableTelemetry":true,
"DisplayBookmarksToolbar":"newtab",
"DisplayMenuBar":"default-off",
"DontCheckDefaultBrowser":true,
"DownloadDirectory":"${home}/Downloads",
"ExtensionUpdate":true,
"NetworkPrediction":false,
"NoDefaultBookmarks":true,
"OfferToSaveLogins":false,
"OverrideFirstRunPage":"",
"OverridePostUpdatePage":"",
"PasswordManagerEnabled":false,
"PrintingEnabled":false,
"PromptForDownloadLocation":false,
"RequestedLocales":"en-US",
"SearchSuggestEnabled":false,
"ShowHomeButton":true,
"SkipTermsOfUse":true,
"TranslateEnabled":false,
"UseSystemPrintDialog":false,
"PDFjs":{
"Enabled":false,
"EnablePermissions":false
},
"PictureInPicture":{
"Enabled":false,
"Locked":false
},
"FirefoxSuggest":{
"WebSuggestions":false,
"SponsoredSuggestions":false,
"ImproveSuggest":false,
"Locked":false
},
"DNSOverHTTPS":{
"Enabled":false,
"Locked":true
},
"UserMessaging":{
"ExtensionRecommendations":false,
"FeatureRecommendations":false,
"UrlbarInterventions":false,
"SkipOnboarding":false,
"MoreFromMozilla":false,
"FirefoxLabs": false,
"Locked":false
},
"Permissions":{
"Location":{
"BlockNewRequests":true
},
"Camera":{
"BlockNewRequests":true
},
"Microphone":{
"BlockNewRequests":true
},
"EncryptedMediaExtensions":{
"Enabled":false,
"Locked":true
}
},
"ExtensionSettings":{
"uBlock0@raymondhill.net":{
"installation_mode":"force_installed",
"install_url":"https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi"
},
"{73a6fe31-595d-460b-a920-fcc0f8843232}":{
"installation_mode":"force_installed",
"install_url":"https://addons.mozilla.org/firefox/downloads/latest/noscript/latest.xpi"
}
},
"3rdparty":{
"Extensions":{
"uBlock0@raymondhill.net":{
"adminSettings":{
"advancedSettings":[
[
"disableWebAssembly",
"true"
]
],
"advancedUserEnabled":"true",
"externalLists":[
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
],
"importedLists":[
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
],
"dynamicFilteringEnabled":"true",
"dynamicFilteringString":"* google-analytics.com * block\n* googletagmanager.com * block\n* * 3p-script block*\n* * 3p-frame block",
"popupPanelSections":"31",
"hostnameSwitchesString":"no-large-media: behind-the-scene false\nno-csp-reports: * true",
"userFilters":"! fonts\n!*$font,third-party\n!*$font,third-party,domain=~example.com|~example2.net\n\n! all stackoverflow annoying consent banners\n##.js-consent-banner\n\n! some annoying banners\n##.banner > [href]\n",
"selectedFilterLists":[
"ublock-quick-fixes",
"user-filters",
"ublock-filters",
"ublock-badware",
"ublock-privacy",
"ublock-abuse",
"ublock-unbreak",
"adguard-generic",
"adguard-mobile",
"easylist",
"easyprivacy",
"urlhaus-1",
"adguard-annoyance",
"fanboy-annoyance",
"ublock-annoyances",
"plowe-0",
"https://raw.githubusercontent.com/AdguardTeam/FiltersRegistry/master/filters/filter_17_TrackParam/filter.txt",
"https://raw.githubusercontent.com/DandelionSprout/adfilt/master/LegitimateURLShortener.txt"
]
}
}
}
},
"FirefoxHome":{
"Highlights":false,
"Pocket":false,
"Search":false,
"Snippets":false,
"SponsoredPocket":false,
"SponsoredStories":false,
"SponsoredTopSites":false,
"Stories":false,
"TopSites":false,
"Locked":true
},
"GenerativeAI": {
"Enabled":false,
"Chatbot":false,
"LinkPreviews":false,
"TabGroups":false,
"Locked":false
},
"HardwareAcceleration":false,
"Homepage":{
"URL":"about:blank",
"Locked":false,
"StartPage":"none"
},
"SearchEngines":{
"Add":[
{
"Name": "DuckDuckGo Lite",
"Alias": "@duckduckgo",
"Method": "POST",
"URLTemplate": "https://start.duckduckgo.com/lite/?q={searchTerms}",
"PostData": "q={searchTerms}",
"IconURL": ""
},
{
"Name":"DuckDuckGo Custom",
"Alias":"@custom",
"Method": "POST",
"URLTemplate":"https://duckduckgo.com/?q={searchTerms}&kl=wt-wt&kp=-2&kg=p&k5=1&kae=d&ks=l&k1=-1",
"PostData": "q={searchTerms}",
"IconURL":""
},
{
"Name":"SearXNG - searx.be",
"Alias":"@searx",
"Method":"POST",
"URLTemplate":"https://searx.be/?q={searchTerms}",
"PostData": "q={searchTerms}&category_general=on",
"IconURL":""
},
{
"Name":"Qwant",
"Alias":"@qwant",
"Method":"GET",
"URLTemplate":"https://www.qwant.com/?q={searchTerms}",
"IconURL":""
},
{
"Name": "MetaGer",
"Alias": "@metager",
"Method": "GET",
"URLTemplate": "https://metager.org/meta/meta.ger3?eingabe={searchTerms}",
"IconURL": ""
},
{
"Name": "Mojeek",
"Alias": "@mojeek",
"Method": "GET",
"URLTemplate": "https://www.mojeek.com/search?q={searchTerms}",
"IconURL": ""
},
{
"Name":"Startpage",
"Alias":"@startpage",
"URLTemplate":"https://www.startpage.com/sp/search?query={searchTerms}",
"Method":"GET",
"IconURL":""
},
{
"Name":"Brave Search",
"Alias":"@brave",
"Method":"GET",
"URLTemplate":"https://search.brave.com/search?q={searchTerms}",
"IconURL":""
},
{
"Name":"LibreTranslate",
"Alias":"@libre",
"Method":"GET",
"URLTemplate":"https://libretranslate.com/?source=de&target=en&q={searchTerms}",
"IconURL":""
},
{
"Name":"DeepL",
"Alias":"@deepl",
"Method":"GET",
"URLTemplate":"https://deepl.com/en/translator#de/en/{searchTerms}",
"IconURL":""
},
{
"Name":"dict.cc",
"Alias":"@dict",
"Method":"GET",
"URLTemplate":"https://www.dict.cc/?s={searchTerms}",
"IconURL":""
}
],
"Remove":[
"Google",
"Bing",
"Amazon.com",
"eBay",
"Ecosia",
"Twitter",
"Wikipedia"
],
"Default":"DuckDuckGo"
},
"Preferences":{
"dom.disable_window_flip":{
"Value":true,
"Status":"user"
},
"dom.disable_window_move_resize":{
"Value":true,
"Status":"user"
},
"extensions.htmlaboutaddons.recommendations.enabled":{
"Value":false,
"Status":"user"
},
"security.default_personal_cert":{
"Value":"Ask Every Time",
"Status":"user"
},
"browser.contentblocking.category":{
"Value":"strict",
"Status":"user"
},
"browser.search.update":{
"Value":false,
"Status":"user"
},
"accessibility.force_disabled":{
"Value":1,
"Status":"user"
},
"browser.tabs.warnOnClose":{
"Value":false,
"Status":"user"
},
"ui.systemUsesDarkTheme":{
"Value":1,
"Status":"user"
},
"extensions.activeThemeID":{
"Value":"firefox-compact-dark@mozilla.org",
"Status":"user"
},
"browser.theme.dark-private-windows":{
"Value":true,
"Status":"user"
},
"layout.css.light-dark.enabled":{
"Value":true,
"Status":"user"
},
"widget.non-native-theme.scrollbar.dark-themed":{
"Value":true,
"Status":"user"
},
"browser.in-content.dark-mode":{
"Value":true,
"Status":"user"
},
"widget.disable-dark-scrollbar":{
"Value":false,
"Status":"user"
},
"browser.theme.dark-toolbar-theme":{
"Value":true,
"Status":"user"
},
"browser.theme.toolbar-theme":{
"Value":1,
"Status":"user"
}
}
}
}
Web Browser References
Mozilla Firefox Documentation
- Mozilla Firefox - Official policy templates documentation
- Mozilla Firefox - Official release versions
- Mozilla Firefox - Linux olicy templates (GitHub)
- Mozilla Firefox - Definitive answer to settings precedence? #1015 (GitHub)
- Mozilla Firefox - Policy templates discussions
- Mozilla Firefox - Enterprise development - How to add policy support
- Mozilla - MDN Web Docs - Navigator - Instance properties - Language property
- Mozilla Firefox - Searchfox - /firefox-main/source/toolkit/components
Mozilla Firefox Topics
- DISA STIGs - Mozilla Firefox Security Technical Implementation Guide
- opticmelody - firefox-stig-policy - This contains the Firefox policies.json for implementing the Mozilla Firefox STIG version 6
- Tor Browser 12.0 does not respect `user.js`/default settings on first start - Open - Issue created Dec 13, 2022 by ChrisK
- How to remove hard-coded suggestions from URL bar drop-down ? - Reddit
- Mozilla Firefox - Enterprise Policy Generator
Security and Privacy Topics
- Arkenfox Wiki
- Betterfox Wiki
- Privacy-Handbuch - Firefox user.js
- How does Qubes OS provide security?
- What about privacy in non-Whonix qubes?
- Librewolf - Feature Request: Radio Silence by Default for Browser Startup and Background Connections aka "Disable Phone Home" #1779 - Opened by adrelanos (2024)
- Kicksecure Default Browser - Development Considerations
- OS Detection Techniques - Jonathans Blog
- Nmap Network Scanning - Chapter 15. Nmap - Reference Guide - OS Detection
- Mozilla Foundation - Security Advisories
- Firefox ESR Vulnerabilities
- CVE Details - Mozilla Vulnerabilities
- CVE Details - Chromium Vulnerabilities
Qubes Forum Discussion
- Is Firefox really an appropriate default browser for Qubes?
- Can websites track me across different qubes?
- Hardware information masking and spoofing with hypervisor
- Stop telling VMs the exact physical CPU model in the computer #1142
About plugins, add-ons, or extensions
- uBlock Wiki - Blocking mode - Medium mode (optimal for advanced users)
- Tor Project - Can I use plugins, add-ons, or extensions in Tor Browser?
- quBO: Manage uBlock Origin and Tor Browser "the qubes way"
- Should I install a new add-on or extension in Tor Browser like Adblock Plus or uBlock Origin?
Others
- URL Parameters - DuckDuckGo
- Advanced syntax - DuckDuckGo
- ‘t’ URL parameter - DuckDuckGo
- Non-JavaScript Version - DuckDuckGo
- How are parameters sent in an HTTP POST request? - Stack Overflow
Web Browser Privacy Tools
Web Browser Privacy Comparison
- Comparison of web browsers - Wikipedia
- Privacy Tests
- Browser Comparison Tool - Avoid the Hack
- Comparison of Web Browsers - Eylenburg
Other Browsers
- The Servo Parallel Browser Engine Project
- The WebKitGTK Project
- List of web browsers - Wikipedia
- IceCat
- Mullvad Browser
- Midori Browser (WebkitGTK) - GitHub
- Midori Browser (WebkitGTK) - Alpine
- Falkon (formerly QupZilla) (QtWebEngine)
- Dillo (FLTK)
- Pale Moon
- GNOME Web (also known as Epiphany) (WebkitGTK)
- Lynx (Text browser)
- Links2 (Text browser)
- w3m (Text browser)
Browser Fingerprinting Test
- NoScript Fingerprint
- FingerprintJS, Inc
- BrowserLeaks
- BrowserLeaks - Fonts
- BrowserLeaks - Features
- BrowserLeaks - JavaScript
- BrowserLeaks - Canvas
- Cover Your Tracks - EFF
- Browserscan
- AmIUnique
- Device Info
- Browser Audit
- Fingerprint Test - Pet Portal
- Privacy Analyzer - Privacy.net
- Canvas Fingerprint - WebBrowserTools.com
- Browser Checker - BrowserScan.net
- WHOER
- Pixelscan
- Cloudflare Turnstile - NopeCHA
- CreepJS (Github)
- OS Detection Font CSS (Github)
- User-Agent Switcher (Gitlab)
Browser Adblock Test
IP and DNS Leak Test
- DNS Leak Test
- IPLeak.net
- IPLeak.net - json
- zx2c4 - Jason A. Donenfeld - json
- ipify API
- ipify API - json
- IPinfo
- Mullvad - Connection check
- GeoPlugin
Useful list of “about” pages
- about:policies
- about:support
- about:config
- about:preferences#search
- about:networking
- about:logging
- about:about
- about:robots
Rendering issue fixed using html encoding, duh !!!