Tailscale: Difference between revisions

Phobos (talk | contribs)
No edit summary
Add native nftables configuration and update UDP performance optimization section using networkd-dispatcher.
 
Line 8: Line 8:


     # If you would like to use a preauthorized key
     # If you would like to use a preauthorized key
  #authKeyFile = "/run/secrets/tailscale_key";
    #authKeyFile = "/run/secrets/tailscale_key";


   };
   };
Line 18: Line 18:


For more configuration option, refer to <code>[https://search.nixos.org/options?show=services.tailscale services.tailscale]</code> .
For more configuration option, refer to <code>[https://search.nixos.org/options?show=services.tailscale services.tailscale]</code> .
== Native nftables Support (Modern Setup) ==
Recent versions of NixOS encourage the use of [[nftables]] over legacy iptables. Tailscale can be configured to use `nftables` natively, which avoids conflicts and kernel module bloat.
This configuration forces the `nftables` backend and optimizes the service startup:
<syntaxhighlight lang="nixos">
{ config, pkgs, ... }:
{
  # 1. Enable the service and the firewall
  services.tailscale.enable = true;
  networking.nftables.enable = true;
  networking.firewall = {
    enable = true;
    # Always allow traffic from your Tailscale network
    trustedInterfaces = [ "tailscale0" ];
    # Allow the Tailscale UDP port through the firewall
    allowedUDPPorts = [ config.services.tailscale.port ];
  };
  # 2. Force tailscaled to use nftables (Critical for clean nftables-only systems)
  # This avoids the "iptables-compat" translation layer issues.
  systemd.services.tailscaled.serviceConfig.Environment = [
    "TS_DEBUG_FIREWALL_MODE=nftables"
  ];
  # 3. Optimization: Prevent systemd from waiting for network online
  # (Optional but recommended for faster boot with VPNs)
  systemd.network.wait-online.enable = false;
  boot.initrd.systemd.network.wait-online.enable = false;
}
</syntaxhighlight>


== Split DNS ==
== Split DNS ==
Line 87: Line 120:


== Optimize the performance of subnet routers and exit nodes ==
== Optimize the performance of subnet routers and exit nodes ==
Tailscale gives [https://tailscale.com/kb/1320/performance-best-practices#enable-on-each-boot recommendations] on how to optimize UDP throughput of your node.
Tailscale gives [https://tailscale.com/kb/1320/performance-best-practices#enable-on-each-boot recommendations] on how to optimize UDP throughput. For high-throughput nodes (like subnet routers), disabling UDP Generic Receive Offload (GRO) on the physical interface is recommended to prevent packet drops.


You need to have <code>ethtool</code> and <code>networkd-dispatcher</code> installed, and to create the appropriate rule for Tailscale.
In NixOS, this can be automated using `networkd-dispatcher` to ensure the setting persists across reboots and network changes.


Supposing the network device you'll be using is called <code>eth0</code>, you can add the following to your <code>configuration.nix</code>:<syntaxhighlight lang="nixos">
<syntaxhighlight lang="nixos">
services = {
# In environment.systemPackages, ensure you have pkgs.ethtool
  networkd-dispatcher = {
services.networkd-dispatcher = {
    enable = true;
  enable = true;
    rules."50-tailscale" = {
  rules."50-tailscale-optimizations" = {
      onState = ["routable"];
    onState = [ "routable" ];
      script = ''
    script = ''
        ${lib.getExe ethtool} -K eth0 rx-udp-gro-forwarding on rx-gro-list off
      ${pkgs.ethtool}/bin/ethtool -K eth0 rx-udp-gro-forwarding on rx-gro-list off
      '';
    '';
    };
   };
   };
};
};
</syntaxhighlight>
</syntaxhighlight>
''Note: Replace `eth0` with your actual WAN interface name (e.g. `ens192`).''