summaryrefslogtreecommitdiff
path: root/modules/yggdrasil-wg/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/yggdrasil-wg/default.nix')
-rw-r--r--modules/yggdrasil-wg/default.nix18
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
5let 5let
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