From 3ec00be4d03d32a489c969ed3dc5d354d0d80aad Mon Sep 17 00:00:00 2001 From: clerie <git@clerie.de> Date: Thu, 20 Mar 2025 19:06:51 +0100 Subject: [PATCH] profiles/wg-clerie: Migrate wg-clerie to systemd-networkd --- profiles/default.nix | 1 + profiles/wg-clerie/default.nix | 163 +++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 profiles/wg-clerie/default.nix diff --git a/profiles/default.nix b/profiles/default.nix index 04aecfb..3daf86a 100644 --- a/profiles/default.nix +++ b/profiles/default.nix @@ -9,6 +9,7 @@ ./mercury-vm ./netcup ./network-fallback-dhcp + ./wg-clerie ]; } diff --git a/profiles/wg-clerie/default.nix b/profiles/wg-clerie/default.nix new file mode 100644 index 0000000..b6a6bf7 --- /dev/null +++ b/profiles/wg-clerie/default.nix @@ -0,0 +1,163 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.profiles.clerie.wg-clerie; +in + +{ + options = { + profiles.clerie.wg-clerie = { + enable = mkEnableOption "VPN for public static IP"; + privateKeyFile = mkOption { + type = with types; nullOr str; + default = null; + description = "Path to file containing private key for wireguard interface"; + }; + ipv6s = mkOption { + type = with types; listOf str; + default = []; + description = "IPv6 interface addresses"; + }; + ipv4s = mkOption { + type = with types; listOf str; + default = []; + description = "IPv4 interface addresses"; + }; + defaultViaVPN = mkOption { + type = types.bool; + default = true; + description = "Use VPN default route for a protocol, if that protocol is unavailable in the underlay"; + }; + }; + }; + + config = mkIf cfg.enable { + + systemd.network.config.routeTables = { + wg-clerie = 200; + }; + systemd.network.config.addRouteTablesToIPRoute2 = true; + + sops.secrets.wg-clerie = { + owner = "systemd-network"; + group = "systemd-network"; + }; + + systemd.network.netdevs."10-wg-clerie" = { + netdevConfig = { + Kind = "wireguard"; + Name = "wg-clerie"; + }; + wireguardConfig = { + PrivateKeyFile = if cfg.privateKeyFile != null then cfg.privateKeyFile else + config.sops.secrets.wg-clerie.path; + RouteTable = "wg-clerie"; + }; + wireguardPeers = [ + { + PublicKey = "2p1Jqs3bkXbXHFWE6vp1yxHIFoUaZQEARS2nJzbkuBA="; + AllowedIPs = [ "0.0.0.0/0" "::/0" "10.20.30.0/24" "2a01:4f8:c0c:15f1::/113" ]; + Endpoint = "78.47.183.82:51820"; + PersistentKeepalive = 25; + } + ]; + }; + + systemd.network.networks."10-wg-clerie" = { + matchConfig.Name = "wg-clerie"; + address = cfg.ipv6s ++ cfg.ipv4s; + routingPolicyRules = (builtins.map + (ip: { + Priority = 19000; + Family = "ipv6"; + From = ip; + #Type = "table"; + Table = "wg-clerie"; + }) + cfg.ipv6s + ) ++ (builtins.map + (ip: { + Priority = 19001; + Family = "ipv6"; + From = ip; + Type = "unreachable"; + }) + cfg.ipv6s + ) ++ (builtins.map + (ip: { + Priority = 19000; + Family = "ipv4"; + From = ip; + #Type = "table"; + Table = "wg-clerie"; + }) + cfg.ipv4s + ) ++ (builtins.map + (ip: { + Priority = 19001; + Family = "ipv4"; + From = ip; + Type = "unreachable"; + }) + cfg.ipv4s + ) ++ [ + { + Priority = 20000; + Family = "ipv6"; + To = "2a01:4f8:c0c:15f1::1/128"; + IPProtocol = "udp"; + DestinationPort = 51820; + #Type = "table"; + Table = "main"; + } + { + Priority = 20001; + Family = "ipv6"; + To = "2a01:4f8:c0c:15f1::1/128"; + IPProtocol = "udp"; + DestinationPort = 51820; + Type = "unreachable"; + } + { + Priority = 20000; + Family = "ipv4"; + To = "78.47.183.82/32"; + IPProtocol = "udp"; + DestinationPort = 51820; + #Type = "table"; + Table = "main"; + } + { + Priority = 20001; + Family = "ipv4"; + To = "78.47.183.82/32"; + IPProtocol = "udp"; + DestinationPort = 51820; + Type = "unreachable"; + } + { + Priority = 21000; + Family = "both"; + #Type = "table"; + Table = "main"; + } + ] ++ (if cfg.defaultViaVPN then [ + { + Priority = 21001; + Family = "both"; + #Type = "table"; + Table = "wg-clerie"; + } + ] else []) ++ [ + { + Priority = 22000; + Family = "both"; + Type = "unreachable"; + } + ]; + }; + + }; +}