[Guide] Automatically install extensions and configure new (dispvm) hardened Firefox profiles with arkenfox user.js and policies

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?

1 Like

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
1 Like

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 %}
1 Like

We need something better than arkenfox. Unresolved, rejected ticket:

2 Likes

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.

3 Likes

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.

4 Likes

Still no solution to splash screen problem?

1 Like

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.

2 Likes

I can't do more changes in this post, I'm doing an update here.

TLDR

  1. Use Tor Browser for anonymity and advanced fingerprinting protection. See here:
    What about privacy in non-Whonix qubes? - Qubes Documentation
  2. 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 Topics

Security and Privacy Topics

Qubes Forum Discussion

About plugins, add-ons, or extensions

Others

Web Browser Privacy Tools

Web Browser Privacy Comparison

Other Browsers

Browser Fingerprinting Test

Browser Adblock Test

IP and DNS Leak Test

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 !!!

3 Likes