From d2b70c61bf5555df5f81bfa9b05c341cf68463b9 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 26 Jun 2023 12:14:34 +1000 Subject: [PATCH] tailscale: improve MagicDNS setup --- ...0e7eb799eee6976daa35b228c885f0630c55ef626c | 2 + modules/nix/default.nix | 2 +- modules/services/tailscale.nix | 67 +++++++++++-------- 3 files changed, 43 insertions(+), 28 deletions(-) create mode 100644 doc/known-files/2c28f4fe3b4a958cd86b120e7eb799eee6976daa35b228c885f0630c55ef626c diff --git a/doc/known-files/2c28f4fe3b4a958cd86b120e7eb799eee6976daa35b228c885f0630c55ef626c b/doc/known-files/2c28f4fe3b4a958cd86b120e7eb799eee6976daa35b228c885f0630c55ef626c new file mode 100644 index 00000000..5f7c6495 --- /dev/null +++ b/doc/known-files/2c28f4fe3b4a958cd86b120e7eb799eee6976daa35b228c885f0630c55ef626c @@ -0,0 +1,2 @@ +# Added by tailscaled +nameserver 100.100.100.100 diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 6a051599..7445b304 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -140,7 +140,7 @@ in in [ # Only ever in NixOS - (mkRemovedOptionModule [ "nix" "enable" ] "No `nix-darwin` equivilant to this NixOS option.") + (mkRemovedOptionModule [ "nix" "enable" ] "No `nix-darwin` equivalent to this NixOS option.") (mkRemovedOptionModule [ "nix" "daemonCPUSchedPolicy" ] (altOption "nix.daemonProcessType")) (mkRemovedOptionModule [ "nix" "daemonIOSchedClass" ] (altOption "nix.daemonProcessType")) (mkRemovedOptionModule [ "nix" "daemonIOSchedPriority" ] (altOption "nix.daemonIOLowPriority")) diff --git a/modules/services/tailscale.nix b/modules/services/tailscale.nix index da319ebe..6603f53e 100644 --- a/modules/services/tailscale.nix +++ b/modules/services/tailscale.nix @@ -7,13 +7,12 @@ let in { - options.services.tailscale = { - domain = mkOption { - type = types.str; - default = ""; - description = lib.mdDoc "The Tailscale domain. This is displayed at the top left of https://login.tailscale.com/admin, next to the Tailscale logo."; - }; + imports = [ + (mkRemovedOptionModule [ "services" "tailscale" "domain" ] "Tailscale no longer requires setting the search domain manually.") + (mkRemovedOptionModule [ "services" "tailscale" "magicDNS" ] "MagicDNS no longer requires overriding the DNS servers, if this is necessary you can use `services.tailscale.overrideLocalDns`.") + ]; + options.services.tailscale = { enable = mkEnableOption (lib.mdDoc "Tailscale client daemon"); package = mkOption { @@ -23,26 +22,32 @@ in description = lib.mdDoc "The package to use for tailscale"; }; - magicDNS = { - enable = mkOption { - type = types.bool; - default = false; - example = true; - description = lib.mdDoc "Whether to configure networking to work with Tailscale's MagicDNS."; - }; + overrideLocalDns = mkOption { + type = types.bool; + default = false; + example = true; + description = lib.mdDoc '' + This option implements `Override local DNS` as it is not yet implemented in Tailscaled-on-macOS. + + To use this option, in the Tailscale control panel: + 1. at least one DNS server is added + 2. `Override local DNS` is enabled + + As this option sets 100.100.100.100 as your sole DNS server, if the requirements above are not met, + all non-MagicDNS queries WILL fail. + ''; }; }; config = mkIf cfg.enable { - assertions = [ { - assertion = !cfg.magicDNS.enable || config.networking.dns != [ "100.100.100.100" ]; + assertions = [{ + assertion = !cfg.overrideLocalDns || config.networking.dns == [ "100.100.100.100" ]; message = '' - When MagicDNS is enabled, fallback DNS servers need to be set with `networking.dns`. + DNS servers should be configured on the Tailscale control panel when `services.tailscale.overrideLocalDns` is enabled. - Otherwise, Tailscale will take a long time to connect and all DNS queries - will fail until Tailscale has connected. + A race condition can occur when DNS servers are set locally, leading to MagicDNS to not work. ''; - } ]; + }]; environment.systemPackages = [ cfg.package ]; @@ -59,13 +64,21 @@ in }; }; - networking = mkIf cfg.magicDNS.enable { - dns = [ "100.100.100.100" ]; - search = - if cfg.domain == "" then - [ ] - else - [ "${cfg.domain}.beta.tailscale.net" ]; - }; + networking.dns = mkIf cfg.overrideLocalDns [ "100.100.100.100" ]; + + # Ensures Tailscale MagicDNS always works even without adding 100.100.100.100 to DNS servers + environment.etc."resolver/ts.net".text = "nameserver 100.100.100.100"; + + # This file gets created by tailscaled when `Override local DNS` is turned off + environment.etc."resolver/ts.net".knownSha256Hashes = [ + "2c28f4fe3b4a958cd86b120e7eb799eee6976daa35b228c885f0630c55ef626c" + ]; + + # Cleaning up the .orig file is necessary as any files in /etc/resolver will be used. + system.activationScripts.etc.text = mkAfter '' + if [ -e /etc/resolver/ts.net.orig ]; then + rm /etc/resolver/ts.net.orig + fi + ''; }; }