From 3976e392e105b2497623da4f62dc6ee5d762963e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 14 Feb 2025 00:11:19 +0100 Subject: [PATCH 1/3] feat(scripts): add script for syncing Firefox site data & cookie exceptions --- scripts/firefox-sync-exceptions.nu | 120 +++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100755 scripts/firefox-sync-exceptions.nu diff --git a/scripts/firefox-sync-exceptions.nu b/scripts/firefox-sync-exceptions.nu new file mode 100755 index 0000000..9e3e0be --- /dev/null +++ b/scripts/firefox-sync-exceptions.nu @@ -0,0 +1,120 @@ +#! /usr/bin/env nu + +print "This script synchronizes site data & cookie exceptions for Firefox-based browsers with a TOML config file." + +let browsers = [ + { name: "Mullvad Browser" path: "~/.mullvad/mullvadbrowser" } + { name: "Tor Browser" path: "~/.tor project/firefox" } + { name: "Firefox" path: "~/.mozilla/firefox" } +] +let browser = $browsers | input list --display name --fuzzy "Select your browser" + +print $"Looking for profiles in ($browser.path)" +let profiles = ls --short-names ...(glob $browser.path) | where type == "dir" | get name +let profile = $profiles | input list --fuzzy "Select the profile you want to change" + +let db_file = $"($browser.path)/($profile)/permissions.sqlite" + +let config_file = "/etc/nixos/home/browsers/site-data-exceptions.toml" +let config_file = input --default $config_file "Select your config file" + +# get origin & origin attributes separately from single origin string +def split_origin []: string -> record { + let x = $in | split column '^' origin attrs | into record + let attrs = if $x.attrs? != null { + $x.attrs | split row '&' | each {|attr| $attr | split row '='} | into record + } else { {} } + { origin: $in origin_short: $x.origin } | merge $attrs +} + +let db = $db_file | open +let config = $config_file | open + +let exceptions_db = $db | get moz_perms + | where type == "cookie" and permission == 1 and expireType == 0 and expireTime == 0 + | each {|x| $x | merge ($x.origin | split_origin) } +let exceptions_config = $config | get $profile | each {|origin| $origin | split_origin } + +let exceptions_to_insert = $exceptions_config + | filter {|x| ($exceptions_db | where origin_short == $x.origin_short | length) == 0 } + | each {|x| { origin: $x.origin } } + +let exceptions_to_update = $exceptions_config + | each {|x| + let results = $exceptions_db | where origin_short == $x.origin_short and origin != $x.origin + let result = $results.0? + if $result != null { + { id: $result.id origin: $x.origin origin_old: $result.origin } + } else { null } + } + +let exceptions_to_delete = $exceptions_db + | filter {|x| ($exceptions_config | where origin_short == $x.origin_short | length) == 0 } + | each {|x| { id: $x.id origin: $x.origin } } + +let needs_insert = ($exceptions_to_insert | length) > 0 +let needs_update = ($exceptions_to_update | length) > 0 +let needs_delete = ($exceptions_to_delete | length) > 0 +let needs_changes = $needs_insert or $needs_update or $needs_delete + +if $needs_changes == false { + print "No changes neccessary" + exit +} + +mut available_actions = [] + +if $needs_insert { + print "Exceptions to insert:" + print $exceptions_to_insert + $available_actions = $available_actions | append "insert" +} + +if $needs_update { + print "Exceptions to update:" + print $exceptions_to_update + $available_actions = $available_actions | append "update" +} + +if $needs_delete { + print "Exceptions to delete:" + print $exceptions_to_delete + $available_actions = $available_actions | append "delete" +} + +let prompt = "Which of the changes above should be applied?" +let actions = $available_actions | input list --multi $prompt + +if ($actions | length) > 0 { + let time = (date now | into int) / 1000000 | into int + + if $needs_insert and "insert" in $actions { + $exceptions_to_insert | each {|x| + $db | query db ' + INSERT INTO moz_perms (origin, type, permission, expireType, expireTime, modificationTime) + VALUES (:origin, "cookie", 1, 0, 0, :time) + ' --params { origin: $x.origin time: $time } + } + print "Successfully inserted new records" + } + + if $needs_update and "update" in $actions { + $exceptions_to_update | each {|x| + $db | query db ' + UPDATE moz_perms + SET origin = :origin, modificationTime = :time + WHERE id = :id + ' --params { id: $x.id origin: $x.origin time: $time } + } + print "Successfully updated changed records" + } + + if $needs_delete and "delete" in $actions { + $exceptions_to_delete | each {|x| + $db | query db 'DELETE FROM moz_perms WHERE id = :id' --params { id: $x.id } + } + print "Successfully deleted missing records" + } +} else { + print "Not applying any changes" +} From e964443c5de6435a4caabf3addaf281dce818434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 14 Feb 2025 00:14:23 +0100 Subject: [PATCH 2/3] feat(scripts): add script for Tailscale Lock signing of Mullvad nodes --- .../tailscale-lock-sign-mullvad-exit-nodes.nu | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100755 scripts/tailscale-lock-sign-mullvad-exit-nodes.nu diff --git a/scripts/tailscale-lock-sign-mullvad-exit-nodes.nu b/scripts/tailscale-lock-sign-mullvad-exit-nodes.nu new file mode 100755 index 0000000..ea7c0c0 --- /dev/null +++ b/scripts/tailscale-lock-sign-mullvad-exit-nodes.nu @@ -0,0 +1,26 @@ +#! /usr/bin/env nu + +let $status = tailscale lock status --json | from json + +let $nodes = $status | get FilteredPeers +let $nodes_mullvad = $nodes | where Name =~ ".mullvad.ts.net" + +let count_total = $nodes | length +let count_mullvad = $nodes_mullvad | length + +print $"unsigned nodes: ($count_total) total, ($count_mullvad) Mullvad" + +if ($nodes_mullvad | length) == 0 { + print "no Mullvad nodes need to be signed" + return +} + +print "signing Mullvad nodes..." + +$nodes_mullvad | each { |node| + print $"signing ($node.Name)" + tailscale lock sign $node.NodeKey + sleep 0.1sec +} + +print "all Mullvad nodes successfully signed" From 3e52c2b922da69a2a2fa8a8400f4efa01200cffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Schr=C3=B6ter?= <dev@felschr.com> Date: Fri, 14 Feb 2025 00:21:21 +0100 Subject: [PATCH 3/3] fix(vpn): disable IPv6 for nginx Tailscale Mullvad exit nodes currently don't support IPv6 and this is causing issues with nginx (proxy pass) requests timing out and high CPU load. Until Mullvad exit nodes support IPv6, we'll just disable IPv6 for nginx. --- system/vpn.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/system/vpn.nix b/system/vpn.nix index c3d3afb..c8543b4 100644 --- a/system/vpn.nix +++ b/system/vpn.nix @@ -56,4 +56,9 @@ in sslCertificate = "/var/lib/tailscale/certs/${tailnetHost}.crt"; sslCertificateKey = "/var/lib/tailscale/certs/${tailnetHost}.key"; }; + + # TODO Tailscale Mullvad exit nodes currently don't support IPv6 and this is + # causing issues with nginx (proxy pass) requests timing out and high CPU load. + # Until Mullvad exit nodes support IPv6, we'll just disable IPv6 for nginx. + services.nginx.resolver.ipv6 = false; }