Loading nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -1231,6 +1231,7 @@ ./services/networking/syncthing.nix ./services/networking/tailscale.nix ./services/networking/tailscale-auth.nix ./services/networking/tailscale-derper.nix ./services/networking/tayga.nix ./services/networking/tcpcrypt.nix ./services/networking/teamspeak3.nix Loading nixos/modules/services/networking/tailscale-derper.nix 0 → 100644 +132 −0 Original line number Diff line number Diff line { config, lib, pkgs, ... }: let cfg = config.services.tailscale.derper; in { meta.maintainers = with lib.maintainers; [ SuperSandro2000 ]; options = { services.tailscale.derper = { enable = lib.mkEnableOption "Tailscale Derper. See upstream doc <https://tailscale.com/kb/1118/custom-derp-servers> how to configure it on clients"; domain = lib.mkOption { type = lib.types.str; description = "Domain name under which the derper server is reachable."; }; openFirewall = lib.mkOption { type = lib.types.bool; default = true; description = '' Whether to open the firewall for the specified port. Derper requires the used ports to be opened, otherwise it doesn't work as expected. ''; }; package = lib.mkPackageOption pkgs [ "tailscale" "derper" ] { }; stunPort = lib.mkOption { type = lib.types.port; default = 3478; description = '' STUN port to listen on. See online docs <https://tailscale.com/kb/1118/custom-derp-servers#prerequisites> on how to configure a different external port. ''; }; port = lib.mkOption { type = lib.types.port; default = 8010; description = "The port the derper process will listen on. This is not the port tailscale will connect to."; }; verifyClients = lib.mkOption { type = lib.types.bool; default = false; description = '' Whether to verify clients against a locally running tailscale daemon if they are allowed to connect to this node or not. ''; }; }; }; config = lib.mkIf cfg.enable { networking.firewall = lib.mkIf cfg.openFirewall { # port 80 and 443 are opened by nginx already allowedUDPPorts = [ cfg.stunPort ]; }; services = { nginx = { enable = true; upstreams.tailscale-derper = { servers."127.0.0.1:${toString cfg.port}" = { }; extraConfig = '' keepalive 64; ''; }; virtualHosts."${cfg.domain}" = { addSSL = true; # this cannot be forceSSL as derper sends some information over port 80, too. locations."/" = { proxyPass = "http://tailscale-derper"; proxyWebsockets = true; extraConfig = '' keepalive_timeout 0; proxy_buffering off; ''; }; }; }; tailscale.enable = lib.mkIf cfg.verifyClients true; }; systemd.services.tailscale-derper = { serviceConfig = { ExecStart = "${lib.getExe' cfg.package "derper"} -a :${toString cfg.port} -c /var/lib/derper/derper.key -hostname=${cfg.domain} -stun-port ${toString cfg.stunPort}" + lib.optionalString cfg.verifyClients " -verify-clients"; DynamicUser = true; Restart = "always"; RestartSec = "5sec"; # don't crash loop immediately StateDirectory = "derper"; Type = "simple"; CapabilityBoundingSet = [ "" ]; DeviceAllow = null; LockPersonality = true; NoNewPrivileges = true; MemoryDenyWriteExecute = true; PrivateDevices = true; PrivateUsers = true; ProcSubset = "pid"; ProtectClock = true; ProtectControlGroups = true; ProtectHostname = true; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectProc = "invisible"; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; RestrictNamespaces = true; RestrictRealtime = true; SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service" ]; }; wantedBy = [ "multi-user.target" ]; }; }; } pkgs/servers/tailscale/default.nix +4 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ buildGoModule { pname = "tailscale"; inherit version; outputs = [ "out" "derper" ]; src = fetchFromGitHub { owner = "tailscale"; repo = "tailscale"; Loading @@ -43,7 +45,7 @@ buildGoModule { CGO_ENABLED = 0; subPackages = [ "cmd/tailscaled" ]; subPackages = [ "cmd/derper" "cmd/tailscaled" ]; ldflags = [ "-w" Loading @@ -60,6 +62,7 @@ buildGoModule { postInstall = '' ln -s $out/bin/tailscaled $out/bin/tailscale moveToOutput "bin/derper" "$derper" '' + lib.optionalString stdenv.hostPlatform.isLinux '' wrapProgram $out/bin/tailscaled \ --prefix PATH : ${lib.makeBinPath [ iproute2 iptables getent shadow ]} \ Loading Loading
nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -1231,6 +1231,7 @@ ./services/networking/syncthing.nix ./services/networking/tailscale.nix ./services/networking/tailscale-auth.nix ./services/networking/tailscale-derper.nix ./services/networking/tayga.nix ./services/networking/tcpcrypt.nix ./services/networking/teamspeak3.nix Loading
nixos/modules/services/networking/tailscale-derper.nix 0 → 100644 +132 −0 Original line number Diff line number Diff line { config, lib, pkgs, ... }: let cfg = config.services.tailscale.derper; in { meta.maintainers = with lib.maintainers; [ SuperSandro2000 ]; options = { services.tailscale.derper = { enable = lib.mkEnableOption "Tailscale Derper. See upstream doc <https://tailscale.com/kb/1118/custom-derp-servers> how to configure it on clients"; domain = lib.mkOption { type = lib.types.str; description = "Domain name under which the derper server is reachable."; }; openFirewall = lib.mkOption { type = lib.types.bool; default = true; description = '' Whether to open the firewall for the specified port. Derper requires the used ports to be opened, otherwise it doesn't work as expected. ''; }; package = lib.mkPackageOption pkgs [ "tailscale" "derper" ] { }; stunPort = lib.mkOption { type = lib.types.port; default = 3478; description = '' STUN port to listen on. See online docs <https://tailscale.com/kb/1118/custom-derp-servers#prerequisites> on how to configure a different external port. ''; }; port = lib.mkOption { type = lib.types.port; default = 8010; description = "The port the derper process will listen on. This is not the port tailscale will connect to."; }; verifyClients = lib.mkOption { type = lib.types.bool; default = false; description = '' Whether to verify clients against a locally running tailscale daemon if they are allowed to connect to this node or not. ''; }; }; }; config = lib.mkIf cfg.enable { networking.firewall = lib.mkIf cfg.openFirewall { # port 80 and 443 are opened by nginx already allowedUDPPorts = [ cfg.stunPort ]; }; services = { nginx = { enable = true; upstreams.tailscale-derper = { servers."127.0.0.1:${toString cfg.port}" = { }; extraConfig = '' keepalive 64; ''; }; virtualHosts."${cfg.domain}" = { addSSL = true; # this cannot be forceSSL as derper sends some information over port 80, too. locations."/" = { proxyPass = "http://tailscale-derper"; proxyWebsockets = true; extraConfig = '' keepalive_timeout 0; proxy_buffering off; ''; }; }; }; tailscale.enable = lib.mkIf cfg.verifyClients true; }; systemd.services.tailscale-derper = { serviceConfig = { ExecStart = "${lib.getExe' cfg.package "derper"} -a :${toString cfg.port} -c /var/lib/derper/derper.key -hostname=${cfg.domain} -stun-port ${toString cfg.stunPort}" + lib.optionalString cfg.verifyClients " -verify-clients"; DynamicUser = true; Restart = "always"; RestartSec = "5sec"; # don't crash loop immediately StateDirectory = "derper"; Type = "simple"; CapabilityBoundingSet = [ "" ]; DeviceAllow = null; LockPersonality = true; NoNewPrivileges = true; MemoryDenyWriteExecute = true; PrivateDevices = true; PrivateUsers = true; ProcSubset = "pid"; ProtectClock = true; ProtectControlGroups = true; ProtectHostname = true; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectProc = "invisible"; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; RestrictNamespaces = true; RestrictRealtime = true; SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service" ]; }; wantedBy = [ "multi-user.target" ]; }; }; }
pkgs/servers/tailscale/default.nix +4 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ buildGoModule { pname = "tailscale"; inherit version; outputs = [ "out" "derper" ]; src = fetchFromGitHub { owner = "tailscale"; repo = "tailscale"; Loading @@ -43,7 +45,7 @@ buildGoModule { CGO_ENABLED = 0; subPackages = [ "cmd/tailscaled" ]; subPackages = [ "cmd/derper" "cmd/tailscaled" ]; ldflags = [ "-w" Loading @@ -60,6 +62,7 @@ buildGoModule { postInstall = '' ln -s $out/bin/tailscaled $out/bin/tailscale moveToOutput "bin/derper" "$derper" '' + lib.optionalString stdenv.hostPlatform.isLinux '' wrapProgram $out/bin/tailscaled \ --prefix PATH : ${lib.makeBinPath [ iproute2 iptables getent shadow ]} \ Loading