1{
2 config,
3 lib,
4 pkgs,
5 self,
6 ...
7}: {
8 options.myNixOS.services.tailscale = {
9 enable = lib.mkEnableOption "Tailscale VPN service";
10
11 authKeyFile = lib.mkOption {
12 description = "Key file to use for authentication";
13 default = config.age.secrets.tailscaleAuthKey.path or null;
14 type = lib.types.nullOr lib.types.path;
15 };
16
17 enableCaddy = lib.mkOption {
18 description = "Whether to serve supported local services on Tailnet with Caddy.";
19 default = true;
20 type = lib.types.bool;
21 };
22
23 operator = lib.mkOption {
24 description = "Tailscale operator name";
25 default = null;
26 type = lib.types.nullOr lib.types.str;
27 };
28 };
29
30 config = lib.mkIf config.myNixOS.services.tailscale.enable {
31 assertions = [
32 {
33 assertion = config.myNixOS.services.tailscale.authKeyFile != null;
34 message = "config.tailscale.authKeyFile cannot be null.";
35 }
36 ];
37
38 age.secrets.caddy.file = "${self.inputs.secrets}/caddy.age";
39
40 home-manager.sharedModules = [
41 {
42 programs.gnome-shell.extensions = [
43 {package = pkgs.gnomeExtensions.tailscale-qs;}
44 ];
45 }
46 ];
47
48 networking.firewall = {
49 allowedUDPPorts = [config.services.tailscale.port];
50 trustedInterfaces = [config.services.tailscale.interfaceName];
51 };
52
53 services.caddy = lib.mkIf config.myNixOS.services.tailscale.enableCaddy {
54 enable = true;
55
56 virtualHosts = {
57 "${config.networking.hostName}.${config.mySnippets.tailnet.name}".extraConfig = let
58 syncthing = ''
59 redir /syncthing /syncthing/
60 handle_path /syncthing/* {
61 reverse_proxy localhost:8384 {
62 header_up Host localhost
63 }
64 }
65 '';
66 in
67 lib.concatLines (
68 lib.optional config.services.syncthing.enable syncthing
69 );
70 };
71 };
72
73 services.tailscale = {
74 enable = true;
75 inherit (config.myNixOS.services.tailscale) authKeyFile;
76
77 extraUpFlags =
78 ["--ssh"]
79 ++ lib.optional (config.myNixOS.services.tailscale.operator != null)
80 "--operator ${config.myNixOS.services.tailscale.operator}";
81
82 extraSetFlags = ["--ssh"];
83
84 openFirewall = true;
85 permitCertUid = lib.mkIf config.services.caddy.enable "caddy";
86 useRoutingFeatures = "both";
87 };
88
89 # who's the devil who made it impossible for this to work dude
90 # this is so dirty
91 systemd.services.tailscaled.serviceConfig.Environment = lib.mkAfter [
92 "TS_NO_LOGS_NO_SUPPORT=true"
93 ];
94 networking.hosts = {
95 "0.0.0.0" = ["log.tailscale.com"];
96 };
97 };
98}