diff options
Diffstat (limited to 'modules/yggdrasil-wg/default.nix')
-rw-r--r-- | modules/yggdrasil-wg/default.nix | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/modules/yggdrasil-wg/default.nix b/modules/yggdrasil-wg/default.nix index d73c7f3f..9ecbe663 100644 --- a/modules/yggdrasil-wg/default.nix +++ b/modules/yggdrasil-wg/default.nix | |||
@@ -4,6 +4,7 @@ with lib; | |||
4 | 4 | ||
5 | let | 5 | let |
6 | listenPort = 51820; | 6 | listenPort = 51820; |
7 | udp2rawPort = 51821; | ||
7 | subnet = "2a03:4000:52:ada:1"; | 8 | subnet = "2a03:4000:52:ada:1"; |
8 | subnetLength = 80; | 9 | subnetLength = 80; |
9 | hostLength = subnetLength + 16; | 10 | hostLength = subnetLength + 16; |
@@ -47,13 +48,13 @@ let | |||
47 | hostLinks = filter ({ from, to, ... }: from == hostName || to == hostName) links; | 48 | hostLinks = filter ({ from, to, ... }: from == hostName || to == hostName) links; |
48 | hostRoutes = filter ({ from, to, ... }: from == hostName || to == hostName) routes; | 49 | hostRoutes = filter ({ from, to, ... }: from == hostName || to == hostName) routes; |
49 | isRouter = inNetwork && any ({via, ...}: via == hostName) routes; | 50 | isRouter = inNetwork && any ({via, ...}: via == hostName) routes; |
50 | linkToPeer = opts@{from, to, ...}: | 51 | linkToPeer = ix: opts@{from, to, ...}: |
51 | let | 52 | let |
52 | other = if from == hostName then to else from; | 53 | other = if from == hostName then to else from; |
53 | in { | 54 | in { |
54 | allowedIPs = hostIPs.${other} ++ concatMap (rArgs: if rArgs.from != hostName || rArgs.via != to then [] else hostIPs.${rArgs.to}) routes; | 55 | allowedIPs = hostIPs.${other} ++ concatMap (rArgs: if rArgs.from != hostName || rArgs.via != to then [] else hostIPs.${rArgs.to}) routes; |
55 | publicKey = trim (readFile (mkPublicKeyPath other)); | 56 | publicKey = trim (readFile (mkPublicKeyPath other)); |
56 | } // (optionalAttrs (from == hostName) (filterAttrs (n: _v: !(elem n ["from" "to" "endpointHost"])) opts // optionalAttrs (opts ? "endpointHost") { endpoint = "${opts.endpointHost}:${toString listenPort}"; })); | 57 | } // (optionalAttrs (from == hostName) (filterAttrs (n: _v: !(elem n ["from" "to" "endpointHost"])) opts // optionalAttrs (opts ? "endpointHost") { endpoint = "localhost:${toString (udp2rawPort + ix)}"; })); |
57 | 58 | ||
58 | trim = str: if hasSuffix "\n" str then trim (removeSuffix "\n" str) else str; | 59 | trim = str: if hasSuffix "\n" str then trim (removeSuffix "\n" str) else str; |
59 | stripSubnet = addr: let matchRes = builtins.match "^(.*)/[0-9]+$" addr; in if matchRes == null then addr else elemAt matchRes 0; | 60 | stripSubnet = addr: let matchRes = builtins.match "^(.*)/[0-9]+$" addr; in if matchRes == null then addr else elemAt matchRes 0; |
@@ -73,7 +74,7 @@ in { | |||
73 | allowedIPsAsRoutes = false; | 74 | allowedIPsAsRoutes = false; |
74 | inherit listenPort; | 75 | inherit listenPort; |
75 | ips = hostIPs.${hostName}; | 76 | ips = hostIPs.${hostName}; |
76 | peers = map linkToPeer hostLinks; | 77 | peers = imap0 linkToPeer hostLinks; |
77 | privateKeyFile = config.sops.secrets."yggdrasil-wg.priv".path; | 78 | privateKeyFile = config.sops.secrets."yggdrasil-wg.priv".path; |
78 | postSetup = '' | 79 | postSetup = '' |
79 | ${concatMapStringsSep "\n" (linkArgs: let other = if linkArgs.from == hostName then linkArgs.to else linkArgs.from; in concatMapStringsSep "\n" (otherIP: "ip route replace \"${otherIP}\" dev \"yggdrasil\" table \"main\"") hostIPs.${other}) hostLinks} | 80 | ${concatMapStringsSep "\n" (linkArgs: let other = if linkArgs.from == hostName then linkArgs.to else linkArgs.from; in concatMapStringsSep "\n" (otherIP: "ip route replace \"${otherIP}\" dev \"yggdrasil\" table \"main\"") hostIPs.${other}) hostLinks} |
@@ -82,6 +83,16 @@ in { | |||
82 | }; | 83 | }; |
83 | }; | 84 | }; |
84 | 85 | ||
86 | systemd.services = listToAttrs (filter ({ value, ...}: value != null) (imap0 (ix: opts@{to, from, ...}: let other = if from == hostName then to else from; in nameValuePair "yggdrasil-udp2raw@${other}" (if opts ? "endpointHost" then { | ||
87 | requiredBy = ["wireguard-yggdrasil.service"]; | ||
88 | |||
89 | serviceConfig = { | ||
90 | ExecStart = "${pkgs.udp2raw}/bin/udp2raw ${if from == hostName then "-c -l localhost:${toString (udp2rawPort + ix)} -r ${opts.endpointHost}:${toString (udp2rawPort + ix)}" else "-s -l 0.0.0.0:${toString (udp2rawPort + ix)} -r localhost:${toString listenPort}"} -k tmpkey --auth-mode hmac_sha1 --raw-mode faketcp -a"; | ||
91 | }; | ||
92 | } else null)) hostLinks)) // { | ||
93 | firewall.path = optionals isRouter [pkgs.procps]; | ||
94 | }; | ||
95 | |||
85 | sops.secrets = mkIf (pathExists privateKeyPath) { | 96 | sops.secrets = mkIf (pathExists privateKeyPath) { |
86 | "yggdrasil-wg.priv" = { | 97 | "yggdrasil-wg.priv" = { |
87 | format = "binary"; | 98 | format = "binary"; |
@@ -91,7 +102,6 @@ in { | |||
91 | 102 | ||
92 | networking.hosts = mkIf inNetwork (listToAttrs (concatMap ({name, value}: map (ip: nameValuePair (stripSubnet ip) ["${name}.yggdrasil"]) value) (mapAttrsToList nameValuePair hostIPs))); | 103 | networking.hosts = mkIf inNetwork (listToAttrs (concatMap ({name, value}: map (ip: nameValuePair (stripSubnet ip) ["${name}.yggdrasil"]) value) (mapAttrsToList nameValuePair hostIPs))); |
93 | 104 | ||
94 | systemd.services.firewall.path = optionals isRouter [pkgs.procps]; | ||
95 | networking.firewall = mkIf isRouter { | 105 | networking.firewall = mkIf isRouter { |
96 | extraCommands = '' | 106 | extraCommands = '' |
97 | ip6tables -A FORWARD -i yggdrasil -o yggdrasil -j nixos-fw-accept | 107 | ip6tables -A FORWARD -i yggdrasil -o yggdrasil -j nixos-fw-accept |