diff options
Diffstat (limited to 'nix')
-rw-r--r-- | nix/default.nix | 234 | ||||
-rw-r--r-- | nix/lib.nix | 77 | ||||
-rw-r--r-- | nix/mozlz4.nix | 24 | ||||
-rw-r--r-- | nix/search.nix | 28 |
4 files changed, 363 insertions, 0 deletions
diff --git a/nix/default.nix b/nix/default.nix new file mode 100644 index 0000000..b3ac1c2 --- /dev/null +++ b/nix/default.nix @@ -0,0 +1,234 @@ +with import <nixpkgs> {}; + +# http://kb.mozillazine.org/About:config_entries +# https://www.privacy-handbuch.de/download/moderat/user.js + +rec { + profiles = callPackage ./lib.nix {}; + search = callPackage ./search.nix {}; + + # Normandy enables Mozilla to push changes to the default settings + disableNormandy = { + app.normandy = { + enabled = false; + api_url = ""; + }; + }; + + disableTelemetry = { + toolkit.telemetry = { + enabled = false; + server = ""; + unified = false; + archive.enabled = false; + + newProfilePing.enabled = false; + firstShutdownPing.enabled = false; + shutdownPing.enabled = false; + updatePing.enabled = false; + }; + }; + + disableErrorReporting = { + breakpad.reportUrl = ""; + }; + + basic = { + network.captive-portal-service.enabled = false; + + # don't update search engines + browser.search = { + update = false; + geoSpecificDefaults = false; + "geoSpecificDefaults.url" = ""; + geoip.url = ""; + suggest.enabled = false; + reset.enabled = false; + reset.whitelist = ""; + }; + + # disable studies + # https://blog.mozilla.org/firefox/update-looking-glass-add/ + # https://mozilla.github.io/normandy/user/end_user_interaction.html#opt-out-preference + app.shield.optoutstudies.enabled = false; + + # disable pocket + extensions.pocket.enabled = false; + }; + + profile = profiles.profile { + preferences = basic; + search = search.mkSearchConfig { + engines = [ search.engines.qwantjunior ]; + }; + }; + + bundle = profiles.bundle { + # https://github.com/mozilla/policy-templates, about:policies#documentation + policies = { + BlockAboutAddons = false; + BlockAboutConfig = false; + BlockAboutProfiles = true; + + CaptivePortal = false; + + DisableMasterPasswordCreation = true; + DisableAppUpdate = true; + DisableFeedbackCommands = true; + DisableFirefoxAccounts = true; + DisableFirefoxStudies = true; + DisableFormHistory = true; + DisablePasswordReveal = true; + DisablePocket = true; + DisableProfileImport = true; + DisableProfileRefresh = true; + + DisableSecurityBypass = { + InvalidCertificate = true; + SafeBrowsing = false; + }; + + DisableSystemAddonUpdate = true; + DisableTelemetry = true; + + DNSOverHTTPS = { + Enabled = false; + Locked = true; + }; + + DontCheckDefaultBrowser = true; + + EnableTrackingProtection = { + Cryptomining = true; + Fingerprinting = true; + Value = true; + }; + + "3rdparty".Extensions = { + # uBlock Origin + "uBlock0@raymondhill.net".adminSettings = builtins.readFile ../ublock-config.json; + # Privacy Badger + "jid1-MnnxcxisBPnSXQ@jetpack" = { + showIntroPage = false; + }; + }; + + ExtensionSettings = + let + fetchAddon = args: "file://${pkgs.fetchurl args}"; + addon = args: { + installation_mode = "force_installed"; + install_url = fetchAddon args; + }; + in { + "*" = { + blocked_install_message = "Installation von Erweiterungen ist nicht zugelassen."; + install_sources = ["https://addons.mozilla.org/"]; + installation_mode = "blocked"; + allowed_types = ["extension"]; + }; + # Extension IDs as keys, .applications.gecko.id in manifest.json + # uBlock Origin + "uBlock0@raymondhill.net" = addon { + url = "https://addons.mozilla.org/firefox/downloads/file/3509800/ublock_origin-1.25.0-an+fx.xpi"; + sha256 = "0pyna4c2b2ffh8ifjj4c8ga9b73g37pk432nyinf8majyb1fq6rc"; + }; + # Privacy Badger + "jid1-MnnxcxisBPnSXQ@jetpack" = addon { + url = "https://addons.mozilla.org/firefox/downloads/file/3509922/privacy_badger-2020.2.19-an+fx.xpi"; + sha256 = "1issggv5wl5x3a4p3q8hrhbkhgsdx9f2qzbscg6y6f75yazswc20"; + }; + # NoScript + "{73a6fe31-595d-460b-a920-fcc0f8843232}" = addon { + url = "https://addons.mozilla.org/firefox/downloads/file/3517653/noscript_security_suite-11.0.15-an+fx.xpi"; + sha256 = "0gb0a6pp0rj9jpg1094arqvcwxh1rd2m47ijawlidybm29qmyyay"; + }; + }; + ExtensionUpdate = false; + + FlashPlugin.Default = false; + + FirefoxHome = { + Search = true; + TopSites = false; + Highlights = false; + Pocket = false; + Snippets = false; + Locked = true; + }; + + Homepage.StartPage = "none"; + + NewTabPage = false; + NoDefaultBookmarks = true; + NetworkPrediction = false; + + OfferToSaveLogins = false; + OverrideFirstRunPage = ""; + OverridePostUpdatePage = ""; + + PasswordManagerEnabled = false; + + Permissions.Location = { + BlockNewRequests = true; + Locked = true; + }; + + Preferences = profiles.flattenAttrs { + app.update.auto = false; + + browser = { + cache.disk.enable = false; + fixup.dns_first_for_single_words = true; + + safebrowsing = { + phishing.enabled = false; + malware.enabled = false; + }; + + search.update = false; + slowStartup.notificationDisabled = true; + }; + + dom.event.contextmenu.enabled = false; + + extensions = { + blocklist.enabled = false; + getAddons.showPane = false; + htmlaboutaddons.recommendations.enabled = false; + }; + + geo.enabled = false; + + media = { + eme.enabled = false; + gmp-gmpopenh264.enabled = false; + gmp-widevinecdm.enabled = false; + peerconnection.enabled = false; + }; + + network.IDN_show_punycode = true; + + security.ssl.errorReporting.enabled = false; + }; + + Proxy = { + Mode = "none"; + Locked = true; + }; + + RequestedLocales = [ "de-DE" "en-US" ]; + + SanitizeOnShutdown = true; + + SearchBar = "separate"; + SearchSuggestEnabled = false; + + SearchEngines = { + Remove = [ "twitter" "bing" ]; + }; + }; + }; + + launcher = profiles.launcher bundle; +} diff --git a/nix/lib.nix b/nix/lib.nix new file mode 100644 index 0000000..df1097f --- /dev/null +++ b/nix/lib.nix @@ -0,0 +1,77 @@ +{ pkgs, lib }: + +with lib; +rec { + mozlz4 = pkgs.callPackage ./mozlz4.nix {}; + + flattenAttrs = set: + let recurse = k: v: + if isAttrs v + then mapAttrsToList (k': recurse "${k}.${k'}") v + else nameValuePair k v; + in listToAttrs (flatten (mapAttrsToList recurse set)); + + mkValueString = v: + if isInt v then toString v + else if isString v then "\"${v}\"" + else if true == v then "true" + else if false == v then "false" + else abort "unsupported value type: ${builtins.typeOf v}"; + + toUserPrefs = settings: pkgs.writeText "user.js" + (lib.concatStringsSep "\n" + (lib.mapAttrsToList (k: v: "user_pref(\"${k}\", ${mkValueString v});") + (flattenAttrs settings))); + + toSearchConfig = settings: pkgs.runCommand "search.json.mozlz4" {} '' + ${mozlz4.compress} < ${pkgs.writeText "search.json" (builtins.toJSON settings)} > $out + ''; + + profile = { preferences, search }: pkgs.runCommand "profile" {} '' + mkdir $out + ln -s ${toUserPrefs preferences} $out/user.js + # ln -s ${toSearchConfig search} $out/search.json.mozlz4 + cp ${../search-with-qj.json.mozlz4} $out/search.json.mozlz4 + ''; + + mkPolicies = policies: pkgs.writeText "policies.json" (builtins.toJSON { + inherit policies; + }); + + bundle = { policies }: + let + firefox = pkgs.firefox-unwrapped; + patched = pkgs.runCommand "firefox-bundle" { + nativeBuildInputs = [ pkgs.nix ]; + disallowedReferences = [ firefox ]; + } '' + cp -r ${firefox} $out + chmod -R +w $out + substituteInPlace $out/bin/firefox \ + --replace ${firefox} $out + + mkdir $out/lib/firefox/distribution + cp ${mkPolicies policies} $out/lib/firefox/distribution/policies.json + ''; + wrapped = pkgs.wrapFirefox patched { + browserName = "firefox"; + version = "custom"; + }; + in wrapped; + + launcher = firefox: pkgs.writeShellScriptBin "firefox" '' + # FF doesn't accept ro profiles, tries to create lockfile + TMP_PROFILE="$(mktemp -d)" + function finish() { + echo deleting profile + # rm -rv "$TMP_PROFILE" + } + trap finish EXIT + # cp -r ''${profile} "$TMP_PROFILE" + chmod u+rwx -R "$TMP_PROFILE" + + ${firefox}/bin/firefox \ + --no-remote \ + --profile "$TMP_PROFILE" + ''; +} diff --git a/nix/mozlz4.nix b/nix/mozlz4.nix new file mode 100644 index 0000000..1fa0497 --- /dev/null +++ b/nix/mozlz4.nix @@ -0,0 +1,24 @@ +{ pkgs, lib }: + +let + inherit (pkgs.writers) writePython3; + inherit (pkgs.python3Packages) lz4; +in rec { + compress = writePython3 "compress.py" { libraries = [ lz4 ]; } '' + import sys + import lz4.block + + data = lz4.block.compress(sys.stdin.buffer.read()) + data = b'mozLz40\0' + data + + sys.stdout.buffer.write(data) + ''; + + decompress = writePython3 "decompress.py" { libraries = [ lz4 ]; } '' + import sys + import lz4.block + + sys.stdin.buffer.read(8) + sys.stdout.buffer.write(lz4.block.decompress(sys.stdin.buffer.read())) + ''; +} diff --git a/nix/search.nix b/nix/search.nix new file mode 100644 index 0000000..516463a --- /dev/null +++ b/nix/search.nix @@ -0,0 +1,28 @@ +# This tries to create a good-enough search.json.mozlz4 file, but that +# is unsupported, undocumented, and probably going to break every other release. + +{ pkgs, lib }: + +with lib; +rec { + mkSearchConfig = engines: { + version = 1; + buildID = "20200202170918"; + appVersion = "72.0.2"; + locale = "und"; # undetermined (?) + visibleDefaultEngines = [ "qwant-junior" ]; + + metaData.searchDefaultExpir = 1581600883568; + + inherit engines; + }; + + engines = { + qwantjunior = { + _name = "Qwant Junior"; + _shortName = "qwant-junior"; + _loadPath = "[other]addEngineWithDetails:qwantjunior@search.mozilla.org"; + description = "Qwant Junior"; + }; + }; +} |