summary refs log tree commit diff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/common.nix10
-rw-r--r--modules/tailscale.nix62
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);
+}