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

I didn’t realize the other day that Arkenfox’s stuff is a full package that gets updates. Right now I’m temporarily in a mode of just having installed firefox, gone to some website and followed its advice as to what to turn off, doing a few more things myself, then making it a DVM template. And that’s primarily for opening links in emails, though I’ve based a couple of named VMs off the same DVM template as well. Most of my browsing goes on in regular AppVMs devoted to different topics (e.g., one devoted to Qubes and researching how to do things). Those, of course, have memory from one startup to the next. I really need to turn my serious attention back to the way I have my browser VMs set up; it’s next on the big “to do” list. I may well go with something like “split browser” where bookmarks are kept in one qube and browsing happens in another.

Ok I’ve finally managed to get my custom UBlock Origin settings into policies.json.

Here’s how I did it, my full policies.json:

{
  "policies": {
    "Cookies": {
      "AcceptThirdParty": "never",
      "Behavior": "reject-tracker-and-partition-foreign",
      "ExpireAtSessionEnd": true,
      "Locked": false
    },
    "DisablePocket": true,
    "DisableTelemetry": true,
    "DisableFirefoxStudies": true,
    "DisableFirefoxAccounts": true,
    "OfferToSaveLogins": false,
    "OverrideFirstRunPage": "",
    "EnableTrackingProtection": {
      "Value": true,
      "Locked": true,
      "Cryptomining": true,
      "Fingerprinting": true
    },
    "Permissions": {
      "Location": {
        "BlockNewRequests": true
      }
    },
    "ManagedBookmarks": [
      {
        "toplevel_name": "Bookmarks"
      },
      {
        "url": "https://duckduckgo.com",
        "name": "DuckDuckGo"
      }
    ],
    "Extensions": {
      "Install": [
        "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi",
        "https://addons.mozilla.org/firefox/downloads/latest/noscript/latest.xpi"
      ],
      "Uninstall": [
        "amazon@search.mozilla.org",
        "bing@search.mozilla.org",
        "google@search.mozilla.org",
        "wikipedia@search.mozilla.org"
      ]
    },
    "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"
              ],
              [
                "uiTheme",
                "dark"
              ]
            ],
            "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": {
      "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": "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": "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": "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": "Random SearX"
    }
  }
}
3 Likes

Happy you found it useful.

Regarding the updater and prefscleaner, you can place those in /etc/skel of your TemplateVM to have them at your disposal in the AppVMs. You can then move them yourself inside the firefox profile directory or have a script do so and launch them at every vm startup for example.

1 Like

Well done, and thank you for sharing it with everyone.

Just be aware that you have a redundant policy:
"ExtensionSettings" should be used in favor of "Extensions" (which is now deprecated).

"AcceptThirdParty" is also deprecated.

1 Like

First of all, thanks for the guide. Really informative.

I only have one question: I’m trying to apply it to a Fedora disposable vm (I’d prefer to have the latest Firefox version rather than the ESR one, I’m kind of an update junkie), but it seems like there are some differences between Fedora and Debian: for instance, firefox.cfg is nowhere to be found.

Now, this post Firefox configuration in DispVM - #8 by varkya states that I could just copy the content from arkenfox’s user.js into autoconfig.js; so, on a Fedora template, should I just copy the user.js into autoconfig.js, therefore skipping the “adapt user.js into firefox.cfg” part of the guide and follow the rest?

Cheers.

Regarding non-esr firefox: I don’t know tbh. I did read somewhere in the policies that it is a functionality reserved to esr (at least some) and I haven’t tried the autoconfig.

Note that we create that file.

You can definitely try both methods though.

Yep, my bad :slight_smile: The environment variable tricked me - I thought it could only reference an existing file.

Anyway, I tried following it to the end with minor changes (e.g. /usr/lib64/firefox instead of /usr/lib/firefox-esr), but it doesn’t seem to work. I’ll report back as soon as I figure it out. Thanks again, in the meantime!

2 Likes

Hi, I also tried to set it up on Fedora some weeks ago. Btw. also with latest firefox, no ESR.

From my very limited linux understanding such configuration files should be stored in etc instead of lib or lib64, so I tried to place the files in

/etc/firefox/firefox.cfg
/etc/firefox/pref/autoconfig.js
/etc/firefox/policies/policies.json

When I experimented with firefox.cfg + autoconfig.js, it worked. Also policies.json only worked. However with the combination of all three it was erratic, either the one or the other worked, but never both (all three files) together. Now it seems mostly policies work, but not autoconfig.js.

At this point I had no more time to look into it. Note that I also included SearchEngines Add / Remove in policies, which is supposed to function only in ESR (WHY Mozilla?!?).

If anybody has more clue I would be super happy. Below you see the commands on Fedora for reference.

[user@disp1234 ~]$ curl --tlsv1.2 -L https://raw.githubusercontent.com/arkenfox/user.js/master/user.js -o /home/user/user.js
[user@disp1234 ~]$ qvm-copy /home/user/user.js


[user@fedora-36 ~]$ sudo bash
bash-5.2# export firefox_cfg="/etc/firefox/firefox.cfg"
bash-5.2# echo "// IMPORTANT: Start your code on the 2nd line" > $firefox_cfg
bash-5.2# export user_js="/home/user/QubesIncoming/disp1234/user.js"
bash-5.2# cat $user_js | grep "user_pref" | grep -v "// user_pref" >> $firefox_cfg
bash-5.2# export overrides_js="/home/user/QubesIncoming/disp1234/user-overrides.js"
bash-5.2# cat $overrides_js | grep "user_pref" | grep -v "// user_pref" >> $firefox_cfg
bash-5.2# sed -i 's/user_pref/pref/g' $firefox_cfg


bash-5.2# export autoconfig_js="/etc/firefox/pref/autoconfig.js"
bash-5.2# echo 'pref("general.config.filename", "firefox.cfg");' > $autoconfig_js
bash-5.2# echo 'pref("general.config.obscure_value", 0);' >> $autoconfig_js
bash-5.2# unset autoconfig_js firefox_cfg user_js override_js
bash-5.2# shutdown -h now
2 Likes

First of all, ignore my latest post as I launched the commands in the disposable template and not the regular one. That’s why nothing worked. I followed your guide, but while the policies worked (I could see ublock and noscript in my toolbar) arkenfox didn’t. I then tried to put firefox.cfg in /usr/lib64/firefox/ instead of /etc/ and now both arkenfox and the policies seems to work. I don’t know if this is the right way to configure it - actually it’s probably not, I just tried it and it happened to work.

More on /usr/lib64/firefox: Manage Firefox on Fedora

EDIT: Also, I haven’t configured any overrides yet. While this makes me certain that arkenfox is working because a ton of websites are broken for me, I see you configured some in your guide @clarinetthelionking . Perhaps that’s another thing to investigate

2 Likes

Well, I am glad I am not the only one who sometimes makes that particular mistake.

@bayesian
Thank you for sharing this.
I too have done this some time ago, but I’m not sure what the specific variable is to set ‘my filters’ for Ublock Origin in the policies.json, is it:

"dynamicFilteringEnabled": "true",
            "dynamicFilteringString": "* google-analytics.com * block\n* googletagmanager.com * block\n* * 3p-script block*\n* * 3p-frame block",

?

Correct

There’s no ESR for Fedora.

It’s not dvm-template it’s disposableVM.

I carefully followed the instructions, but in the end my disposable-vm does not exactly do what it should. (e.g. some search engines are not removed).

Here is what I did:

  1. Cloned debian-11 template
  2. Followed the instructions above, and used the cloned debian11 template to insert the user.js into firefox.cfg, placed the policies.json in the right directory and so on. All worked fine.
  3. I created a debian-11-DISPVM on basis of a the debian-11-clone-Template
  4. In the end I created a disposable-vm “Firefox-Disp” with the following settings:

Basic: Template debian-11-clone
Advanced: Disposable Template / Default Disposable Template: debian-11-DISPVM
Now, when I start the disposable Firefox-Disp I get an empty page with Noscript and Ublock installed. Default search engine is startpage, although I have to actively select it in the search field. Amazon and wikipedia search are still there, though the policies.json says to uninstall them. Did anyone succeed in placing bookmarks into the policies.json?

I seems the policies.json works in my case only partially.

Did I miss something vital? Any suggestions are welcome.

My second question:
I use a regular app-vm for surfing on basis of fedora-36. The Firefox in there is hardened and fairly secure (ublock,canvas blocker, multi account and temp. container, jshelter and moderate user.js). I use bookmarks and a 30 digit master-password for my passwords (I know there is a better but less convenient solution with Keepass-XC).

With this configuration I cloned the app-vm and made it disposable:

Template: Fedora-36
Advanced: Disposable Template (selected) / Default Disposable Template: Fedora-36-dvm.

When I start the cloned app-vm it naturally starts as disposable with all the above mentioned convenient Firefox ingredients: Now this sounds to good to be true: I have a convenient firefox as I want it to be, and the whole thing is self-destructive after shutdown. My question is now, if there would be any security issue in this configuration. If this would be a fairly secure working solution then it would make the whole configuration with arkenfox user.js, Autoconfig and policies.json look obsolete.

Or do I miss something basic in here?

In your "SearchEngines" policy, add "Default": "<engine name>".

Try to add your local TLD (ie: amazon.com or amazon.de)

Look here.

You’re still subject to profile fingerprinting, since you keep using the same profile that was created the first time in your original AppVM. From a security standpoint, it’s as secure as when you cloned it. It’s up to you to decide what you care about.

Ah…

Thanks for help. Regarding fingerprinting I expected something like what you mentioned.

Other issues as bookmarks, search engines and startpage I was able to solve yesterday. In the end I tried to get even better adjusting policies.json an firefox.cfg and messed it up again and now Google is back and addons are gone. :frowning: A simple bakup of the VM-Template would have been fine. Hope to be able to fix this today.

I get permission denied at this step.

I also checked /usr/lib/firefox-esr and firefox.cfg does not seem to be there

Make sure you have root permissions since you are editing /usr folder. You can run open a terminal in the desired templateVM as root user with:

qvm-run -u root template-something xterm

in the dom0 terminal.

Additionally, please understand that some files, example the /usr/lib/firefox-esr/firefox.cfg, do not exist in a default “vanilla” firefox/firefox-esr fresh install. And the whole idea behind this tutorial is to create some of those files.

2 Likes

Thanks for that, actually got it all working, except about:debugging gets blocked when using this, so I need to figure that out as I upload local addons from time to time for testing.

If anyone knows what setting activates/disables it please let me know as I’ve been stuck for a few hours and have pretty much exhausted the wiki