feat(teal): Add tailscale

We set up a headscale server, but we did not yet add a client so it
isn't possible to use it on the tailnet. Let's do that!

Change-Id: I686a6f6d8df2b4a8dd9d47389aacb0bff3abff82
Reviewed-on: https://git.clicks.codes/c/Infra/NixFiles/+/742
Reviewed-by: Samuel Shuert <coded@clicks.codes>
Tested-by: Skyler Grey <minion@clicks.codes>
diff --git a/modules/nixos/clicks/networking/tailscale/default.nix b/modules/nixos/clicks/networking/tailscale/default.nix
new file mode 100644
index 0000000..29e413a
--- /dev/null
+++ b/modules/nixos/clicks/networking/tailscale/default.nix
@@ -0,0 +1,51 @@
+# SPDX-FileCopyrightText: 2024 Clicks Codes
+#
+# SPDX-License-Identifier: GPL-3.0-only
+
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+let
+  cfg = config.clicks.networking.tailscale;
+in
+{
+  options.clicks.networking.tailscale = {
+    enable = lib.mkEnableOption "Enable tailscale for this system";
+    runExitNode.enable = lib.mkOption {
+      description = "Enable this system as an exit node on the tailnet";
+      default = true;
+      type = lib.types.bool;
+    };
+    server = lib.mkOption {
+      description = "Set where your control plane server is";
+      default = "https://clicks.domains";
+      example = "https://controlplane.tailscale.com";
+    };
+    authKeyFile = lib.mkOption {
+      type = lib.types.str;
+      description = "Path to key file for tailscale";
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    services.tailscale = {
+      enable = true;
+      useRoutingFeatures = if cfg.runExitNode.enable then "both" else "client";
+      extraUpFlags = [
+        "--login-server=${cfg.server}"
+        "--accept-routes"
+        "--ssh"
+      ] ++ (if cfg.runExitNode.enable then [ "--advertise-exit-node" ] else [ ]);
+      authKeyFile = cfg.authKeyFile;
+    };
+
+    clicks.storage.impermanence.persist.directories = [ "/var/lib/tailscale" ];
+
+    systemd.services.tailscaled.environment.TS_NO_LOGS_NO_SUPPORT = lib.mkIf (
+      cfg.server != "https://controlplane.tailscale.com"
+    ) "true";
+  };
+}