Commit 29956b8
Changed files (8)
modules
hosts
cyrene
services
hyacine
services
services
modules/hosts/cyrene/services/default.nix
@@ -41,10 +41,6 @@
services.headscale = {
domain = "gate.trin.one";
port = 3465;
- derp = {
- enable = true;
- addPublicServers = true;
- };
dns = {
enable = true;
domain = "net.trin.one";
@@ -75,6 +71,7 @@
services.headplane
services.headscale
services.ntfy-sh
+ services.tailscale-relay
services.vaultwarden
services.wakapi
];
modules/hosts/hyacine/services/default.nix
@@ -1,11 +1,6 @@
{den, ...}: {
den.hosts.hyacine = {
settings = {
- services.tailscale-derp = {
- domain = "derp-hyacine.trin.one";
- port = 8010;
- };
-
services.xray = {
realitySiteFileAged = ./xray-reality-site.age;
port = 7890;
@@ -21,7 +16,7 @@
den.aspects.hyacine.includes = with den.aspects; [
services.caddy
- services.tailscale-derp
+ services.tailscale-relay
services.caddy.reality
services.xray
modules/services/headscale/_lib.nix
@@ -1,38 +1,6 @@
{lib}: let
inherit (import ../direct-dns/_lib.nix {inherit lib;}) mkDirectEntries;
- hexDigitValue = c:
- lib.lists.findFirstIndex (d: d == c) 0 (lib.stringToCharacters "0123456789abcdef");
-
- mkDerpRegionId = domain:
- 900
- + (
- builtins.foldl' (acc: c: lib.mod (acc * 16 + hexDigitValue c) 99) 0
- (lib.stringToCharacters (builtins.hashString "sha256" domain))
- );
-
- mkDerpNodeLines = r:
- lib.concatStringsSep "\n" (
- [" - name: ${r.h.name}"]
- ++ [" regionid: ${toString r.regionId}"]
- ++ [" hostname: ${r.dcfg.domain}"]
- ++ lib.optionals (r.v4 != null) [" ipv4: \"${r.v4}\""]
- ++ lib.optionals (r.v6 != null) [" ipv6: \"${r.v6}\""]
- ++ [" stunport: 3478"]
- ++ [" derpport: 443"]
- ++ [" stunonly: false"]
- );
-
- mkDerpRegionBlock = r:
- lib.concatStringsSep "\n" (
- [" ${toString r.regionId}:"]
- ++ [" regionid: ${toString r.regionId}"]
- ++ [" regioncode: ${r.h.name}"]
- ++ [" regionname: ${r.h.name}"]
- ++ [" nodes:"]
- ++ [(mkDerpNodeLines r)]
- );
-
mkTailnetEntries = reverseProxy: let
uniqueByDomain = lib.foldl' (acc: e:
if builtins.any (x: x.domain == e.domain) acc
@@ -176,6 +144,4 @@ in {
configFilePath = "/var/lib/headscale/config.yaml";
dnsRecordsFilePath = "/var/lib/headscale/dns-records.json";
-
- inherit mkDerpRegionId mkDerpRegionBlock;
}
modules/services/headscale/default.nix
@@ -5,7 +5,6 @@
}: {
den.aspects.services.headscale = {
includes = [
- den.aspects.services.headscale.derp
den.aspects.services.headscale.dns
den.aspects.services.headscale.policy
];
@@ -19,14 +18,6 @@
type = lib.types.port;
default = 8080;
};
- derp = {
- enable = lib.mkEnableOption "Enable Headscale's builtin DERP server";
- addPublicServers = lib.mkEnableOption "Add public Tailscale DERP servers to DERP map";
- port = lib.mkOption {
- type = lib.types.port;
- default = 3478;
- };
- };
dns = {
enable = lib.mkEnableOption "Enable Headscale's Magic DNS";
domain = lib.mkOption {
@@ -70,7 +61,6 @@
;
cfg = host.settings.services.headscale;
- hostAddr = host.address;
tailnetDomain = den.aspects.services.caddy.tailnetDomain;
@@ -126,7 +116,6 @@
v6 = "fd7a:115c:a1e0::/48";
allocation = "random";
};
- derp.paths = [config.vaultix.templates.headscale-derp-map.path];
};
};
@@ -135,9 +124,6 @@
in {
serviceConfig = {
ExecStartPre = [mergeHeadscaleState];
- EnvironmentFile =
- lib.mkIf (hostAddr.ipv4.secret.name != null || hostAddr.ipv6.secret.name != null)
- config.vaultix.templates.headscale-env.path;
};
script = lib.mkForce ''
modules/services/headscale/derp.nix
@@ -1,129 +0,0 @@
-{den, ...}: {
- den.aspects.services.headscale.derp = {host, ...}: {
- nixos = {
- lib,
- config,
- ...
- }: let
- inherit
- (import ./_lib.nix {inherit lib;})
- mkDerpRegionBlock
- mkDerpRegionId
- ;
-
- cfg = host.settings.services.headscale;
- hostAddr = host.address;
-
- derpHosts = let
- allHosts = builtins.concatMap builtins.attrValues (builtins.attrValues den.hosts);
- in
- builtins.filter (h: h.hasAspect den.aspects.services.tailscale-derp) allHosts;
-
- derpRegions =
- map (h: let
- dcfg = h.settings.services.tailscale-derp;
- v4 = h.address.ipv4;
- v6 = h.address.ipv6;
- in {
- inherit h dcfg;
- regionId = mkDerpRegionId dcfg.domain;
- v4 =
- if v4.clearText != null
- then v4.clearText
- else if v4.secret.name != null && v4.secret.file != null
- then config.vaultix.placeholder.${v4.secret.name}
- else null;
- v6 =
- if v6.clearText != null
- then v6.clearText
- else if v6.secret.name != null && v6.secret.file != null
- then config.vaultix.placeholder.${v6.secret.name}
- else null;
- })
- derpHosts;
-
- duplicateDerpDomains = let
- domains = map (r: r.dcfg.domain) derpRegions;
- in
- lib.filter (d: builtins.length (lib.filter (r: r.dcfg.domain == d) derpRegions) > 1) (lib.unique domains);
-
- collidingDerpRegionIds = lib.filter (r: builtins.length (lib.filter (r': r'.regionId == r.regionId) derpRegions) > 1) derpRegions;
-
- derpersWithoutAddress = lib.filter (r: r.v4 == null && r.v6 == null) derpRegions;
-
- assertUniqueDerpDomains =
- lib.assertMsg (duplicateDerpDomains == [])
- "Multiple DERP hosts declare the same domain: ${lib.concatStringsSep ", " duplicateDerpDomains}";
-
- assertUniqueDerpRegionIds =
- lib.assertMsg (collidingDerpRegionIds == [])
- ("DERP region ID collision between hosts: "
- + lib.concatStringsSep ", " (lib.unique (map (r: r.h.name) collidingDerpRegionIds)));
-
- assertDerpersHaveAddress =
- lib.assertMsg (derpersWithoutAddress == [])
- ("DERP hosts have no public IPv4 or IPv6 (clearText or secret): "
- + lib.concatStringsSep ", " (map (r: r.h.name) derpersWithoutAddress));
-
- derpMapYaml = assert assertUniqueDerpDomains;
- assert assertUniqueDerpRegionIds;
- assert assertDerpersHaveAddress; (
- if derpRegions == []
- then "regions: {}\n"
- else "regions:\n" + lib.concatStringsSep "\n" (map mkDerpRegionBlock derpRegions) + "\n"
- );
-
- hostsWithIpv4Secret =
- builtins.filter (h: h.address.ipv4.secret.name != null && h.address.ipv4.secret.file != null) derpHosts;
- hostsWithIpv6Secret =
- builtins.filter (h: h.address.ipv6.secret.name != null && h.address.ipv6.secret.file != null) derpHosts;
- in {
- services.headscale.settings.derp.server = lib.optionalAttrs (cfg.derp.enable) {
- enabled = true;
- stun_listen_addr = "0.0.0.0:${toString cfg.derp.port}";
- verify_clients = true;
- region_id = 999;
- region_code = "headscale";
- region_name = "Headscale Embedded DERP";
- ipv4 = lib.mkIf (hostAddr.ipv4.clearText != null) hostAddr.ipv4.clearText;
- ipv6 = lib.mkIf (hostAddr.ipv6.clearText != null) hostAddr.ipv6.clearText;
- };
-
- services.headscale.settings.derp.urls = lib.mkIf (!cfg.derp.addPublicServers) [];
-
- networking.firewall.allowedUDPPorts = lib.optional (cfg.derp.enable) cfg.derp.port;
-
- vaultix.secrets = lib.mkMerge (
- (map (h: {${h.address.ipv4.secret.name}.file = h.address.ipv4.secret.file;}) hostsWithIpv4Secret)
- ++ (map (h: {${h.address.ipv6.secret.name}.file = h.address.ipv6.secret.file;}) hostsWithIpv6Secret)
- );
-
- vaultix.templates.headscale-derp-map = {
- content = derpMapYaml;
- owner = config.services.headscale.user;
- group = config.services.headscale.group;
- mode = "0400";
- };
-
- vaultix.templates.headscale-env =
- lib.mkIf (hostAddr.ipv4.secret.name != null || hostAddr.ipv6.secret.name != null)
- {
- content = lib.concatLines (
- (
- lib.optional
- (hostAddr.ipv4.secret.name != null)
- "HEADSCALE_DERP_SERVER_IPV4=${config.vaultix.placeholder.${hostAddr.ipv4.secret.name}}"
- )
- ++ (
- lib.optional
- (hostAddr.ipv6.secret.name != null)
- "HEADSCALE_DERP_SERVER_IPV6=${config.vaultix.placeholder.${hostAddr.ipv6.secret.name}}"
- )
- );
- owner = config.services.headscale.user;
- group = config.services.headscale.group;
- mode = "0400";
- };
- };
- };
-}
modules/services/mihomo/tproxy.nix
@@ -50,8 +50,8 @@
}
set bypass-udp-ports {
type inet_service
- # 3478: STUN; 41641: WireGuard endpoints of Tailscale peers.
- elements = { 53, 67, 68, 123, 3478, 41641 }
+ # 3478: STUN; 40000: peer relay; 41641: WireGuard endpoints of Tailscale peers.
+ elements = { 53, 67, 68, 123, 3478, 40000, 41641 }
}
set bypass-udp-sports {
type inet_service
modules/services/tailscale-derp.nix
@@ -1,36 +0,0 @@
-{lib, ...}: {
- den.aspects.services.tailscale-derp = {
- settings.host = {
- domain = lib.mkOption {
- type = lib.types.str;
- };
- port = lib.mkOption {
- type = lib.types.port;
- default = 8010;
- };
- };
-
- reverseProxy = {host, ...}: let
- cfg = host.settings.services.tailscale-derp;
- in {
- ${cfg.domain} = {
- port = cfg.port;
- prefer = "direct";
- };
- };
-
- nixos = {host, ...}: let
- cfg = host.settings.services.tailscale-derp;
- in {
- services.tailscale.derper = {
- enable = true;
-
- inherit (cfg) domain port;
-
- configureNginx = false;
- openFirewall = true;
- verifyClients = true;
- };
- };
- };
-}
modules/services/tailscale-relay.nix
@@ -0,0 +1,26 @@
+{lib, ...}: {
+ den.aspects.services.tailscale-relay = {
+ settings.host.port = lib.mkOption {
+ type = lib.types.port;
+ default = 40000;
+ description = "UDP port that accepts peer relay connections from tailnet members.";
+ };
+
+ tailscaleGrant = _: [
+ {
+ src = ["autogroup:member"];
+ app."tailscale.com/cap/relay" = [];
+ }
+ ];
+
+ nixos = {host, ...}: let
+ cfg = host.settings.services.tailscale-relay;
+ in {
+ services.tailscale.extraSetFlags = [
+ "--relay-server-port=${toString cfg.port}"
+ ];
+
+ networking.firewall.allowedUDPPorts = [cfg.port];
+ };
+ };
+}