❄️ Dotfiles for our NixOS system configuration.
1# From https://github.com/isabelroses/dotfiles/blob/main/modules/nixos/networking/tailscale.nix
2
3{ lib, config, ... }:
4
5{
6 options = {
7 settings.tailscale = {
8 enable = lib.mkOption {
9 type = lib.types.bool;
10 default = true;
11 description = "Enable Tailscale VPN client/service";
12 };
13
14 defaultFlags = lib.mkOption {
15 type = lib.types.listOf lib.types.str;
16 default = [ "--ssh" ];
17 description = "A list of command-line flags that will be passed to the Tailscale daemon";
18 };
19
20 isServer = lib.mkOption {
21 type = lib.types.bool;
22 default = config.settings.profiles.server.enable;
23 description = "Whether this Tailscale instance is a server/relay node";
24 };
25
26 isClient = lib.mkOption {
27 type = lib.types.bool;
28 default = config.settings.tailscale.enable && !config.settings.tailscale.isServer;
29 description = "Whether this Tailscale instance is a client";
30 };
31 };
32 };
33
34 config = lib.mkIf config.settings.tailscale.enable {
35 settings.firewall.allowedUDPPorts = [ config.services.tailscale.port ];
36
37 networking.firewall = {
38 trustedInterfaces = [ config.services.tailscale.interfaceName ];
39 checkReversePath = false;
40 };
41
42 services.tailscale = {
43 enable = true;
44 permitCertUid = "root";
45 useRoutingFeatures = lib.mkDefault "server";
46 extraUpFlags =
47 config.settings.tailscale.defaultFlags
48 ++ lib.optionals config.settings.tailscale.isServer [ "--advertise-exit-node" ];
49 };
50
51 # A server cannot be a client and vice versa
52 assertions = [
53 {
54 assertion = config.settings.tailscale.isClient != config.settings.tailscale.isServer;
55 message = "Tailscale instance cannot be both a client and a server at the same time.";
56 }
57 ];
58 };
59}