{ config, lib, pkgs, ... }: let vars = import ./vars.nix config; ifs = vars.ifs; ts0 = ifs.ts0; # Subnets advertised to the tailnet (still need to be approved in the admin console) advertisedRoutes = [ "${vars.p4}.0.0/16" # all LAN v4 subnets "${vars.ulaPrefix}::/48" # all LAN ULA subnets ]; in { # One-time setup after deploying: `sudo tailscale up` # (state is persisted in /var/lib/tailscale) services.tailscale = { enable = true; port = ts0.listenPort; interfaceName = ts0.name; # Enables ip forwarding (already enabled globally by networkd anyway). # Not using "both", since that sets rp_filter to loose on all interfaces. useRoutingFeatures = "server"; # Firewall is managed manually in firewall.nix (networking.firewall is disabled) openFirewall = false; # Applied with `tailscale set` on every start, so these stay declarative extraSetFlags = [ # Don't let tailscale touch nftables/iptables, all rules live in firewall.nix "--netfilter-mode=off" # Don't SNAT tailnet -> LAN traffic, LAN hosts route back via the router anyway # (preserves real source addrs for logging/ACLs on LAN hosts) "--snat-subnet-routes=false" # The router is its own DNS server, don't let tailscale mess with resolv.conf "--accept-dns=false" "--advertise-routes=${lib.strings.concatStringsSep "," advertisedRoutes}" "--advertise-exit-node" ]; }; # networkd removes "foreign" ip rules when it (re)starts, which would wipe tailscale's # policy routing rules (table 52). This is extra important since networkd is # restarted every minute (see ifconfig.nix). # The nixpkgs tailscale module already marks tailscale0 as unmanaged in networkd. systemd.network.config.networkConfig.ManageForeignRoutingPolicyRules = false; }