diff options
| -rw-r--r-- | modules/common.nix | 10 | ||||
| -rw-r--r-- | modules/tailscale.nix | 62 |
2 files changed, 64 insertions, 8 deletions
diff --git a/modules/common.nix b/modules/common.nix index 2c183ef..e6aa4d7 100644 --- a/modules/common.nix +++ b/modules/common.nix @@ -7,6 +7,7 @@ ./nix.nix ./user.nix ./locale.nix + ./tailscale.nix ./nix-ld.nix ./vim.nix ]; @@ -27,11 +28,10 @@ networking = { hostName = me.name; - + firewall = { enable = true; allowedTCPPorts = [ 80 443 ]; - trustedInterfaces = [ "tailscale0" ]; }; }; @@ -60,12 +60,6 @@ PermitRootLogin = "no"; }; }; - tailscale = { - enable = true; - useRoutingFeatures = "both"; - extraUpFlags = [ "--ssh" ]; - }; - # sometimes needed for gnupg pcscd.enable = true; }; diff --git a/modules/tailscale.nix b/modules/tailscale.nix new file mode 100644 index 0000000..0aaed8d --- /dev/null +++ b/modules/tailscale.nix @@ -0,0 +1,62 @@ +{ + pkgs, + options, + lib, + ... +}: + +let + inherit (lib) getExe getExe' genAttrs; + + # we use tailscale as the main network provider + # for multiple essential services. + # it's important that tailscale starts up prior + # to them. + vitalServices = [ + "sshd" + "docker" + "nginx" + ]; + + # all metrics exporters are exposed through the tailnet, + # they also need to wait for the tailscale0 interface to be up. + # note that we modify all existing + monitoringServices = map (e: "prometheus-${e}-exporter") ( + builtins.attrNames options.services.prometheus.exporters.value + ); + + servicesNeedingTailscale = vitalServices ++ monitoringServices; + serviceConfigAfterTailscale = { + after = [ "tailscaled.service" ]; + }; +in +{ + # start tailscale :) + services.tailscale = { + enable = true; + useRoutingFeatures = "both"; + extraUpFlags = [ "--ssh" ]; + }; + # tailscale0 is the only interface that is allowed + # to fully bypass the firewall. + networking.firewall.trustedInterfaces = [ "tailscale0" ]; + + systemd.services = { + # the tailscaled systemd service is + # too eager in marking itself ready, + # so we need to ensure it's actually + # up before proceeding with other units. + # see: https://github.com/tailscale/tailscale/issues/11504 + "tailscaled".postStart = with pkgs; '' + echo "Waiting for tailscale0 to come online..." + + for try in in {1..30}; do + if ${getExe' iproute2 "ip"} addr show dev tailscale0 | ${getExe gnugrep} -q 'inet '; then + echo "tailscale0 is up!" + break + fi + sleep 1 + done + ''; + } // genAttrs servicesNeedingTailscale (x: serviceConfigAfterTailscale); +} |
