From 352d9aab099ea7367066c290df45e45e59932b00 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Sun, 10 Oct 2021 13:15:33 +0200 Subject: yggdrasil-wg: udp2raw --- modules/yggdrasil-wg/default.nix | 18 ++++++++++++++---- 1 file 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; let listenPort = 51820; + udp2rawPort = 51821; subnet = "2a03:4000:52:ada:1"; subnetLength = 80; hostLength = subnetLength + 16; @@ -47,13 +48,13 @@ let hostLinks = filter ({ from, to, ... }: from == hostName || to == hostName) links; hostRoutes = filter ({ from, to, ... }: from == hostName || to == hostName) routes; isRouter = inNetwork && any ({via, ...}: via == hostName) routes; - linkToPeer = opts@{from, to, ...}: + linkToPeer = ix: opts@{from, to, ...}: let other = if from == hostName then to else from; in { allowedIPs = hostIPs.${other} ++ concatMap (rArgs: if rArgs.from != hostName || rArgs.via != to then [] else hostIPs.${rArgs.to}) routes; publicKey = trim (readFile (mkPublicKeyPath other)); - } // (optionalAttrs (from == hostName) (filterAttrs (n: _v: !(elem n ["from" "to" "endpointHost"])) opts // optionalAttrs (opts ? "endpointHost") { endpoint = "${opts.endpointHost}:${toString listenPort}"; })); + } // (optionalAttrs (from == hostName) (filterAttrs (n: _v: !(elem n ["from" "to" "endpointHost"])) opts // optionalAttrs (opts ? "endpointHost") { endpoint = "localhost:${toString (udp2rawPort + ix)}"; })); trim = str: if hasSuffix "\n" str then trim (removeSuffix "\n" str) else str; stripSubnet = addr: let matchRes = builtins.match "^(.*)/[0-9]+$" addr; in if matchRes == null then addr else elemAt matchRes 0; @@ -73,7 +74,7 @@ in { allowedIPsAsRoutes = false; inherit listenPort; ips = hostIPs.${hostName}; - peers = map linkToPeer hostLinks; + peers = imap0 linkToPeer hostLinks; privateKeyFile = config.sops.secrets."yggdrasil-wg.priv".path; postSetup = '' ${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 { }; }; + 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 { + requiredBy = ["wireguard-yggdrasil.service"]; + + serviceConfig = { + 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"; + }; + } else null)) hostLinks)) // { + firewall.path = optionals isRouter [pkgs.procps]; + }; + sops.secrets = mkIf (pathExists privateKeyPath) { "yggdrasil-wg.priv" = { format = "binary"; @@ -91,7 +102,6 @@ in { networking.hosts = mkIf inNetwork (listToAttrs (concatMap ({name, value}: map (ip: nameValuePair (stripSubnet ip) ["${name}.yggdrasil"]) value) (mapAttrsToList nameValuePair hostIPs))); - systemd.services.firewall.path = optionals isRouter [pkgs.procps]; networking.firewall = mkIf isRouter { extraCommands = '' ip6tables -A FORWARD -i yggdrasil -o yggdrasil -j nixos-fw-accept -- cgit v1.2.3