{ lib, config, pkgs, ... }: let serverHostName = "vueko"; peers = { nunotaba = { address = "10.80.0.4"; publicKey = "DvR8mUkll4uyYhNcX82caMkbcw0Lykg8zDzm/3PD5jw="; }; sayuri = { address = "10.80.0.5"; publicKey = "t7hpd2yZupAKHxYerHtXnlPRUjV1aGbrrzjYakKdOwE="; }; vueko = { address = "10.80.0.6"; publicKey = "JbOfL4FxPCzJOjI8AGklPHY2FniCXq0QwOa08gjSyns="; }; fuuko = { address = "10.80.0.7"; publicKey = "VXic8mhaJBSl6yFkx0Cu6JI8tqqjjM3UbW7x+05pV0M="; }; }; cfg = config.sbruder.wireguard.home; enableServer = config.networking.hostName == serverHostName; in { options = { sbruder.wireguard.home = { enable = lib.mkEnableOption "WireGuard tunnel wg-home"; address = lib.mkOption { type = lib.types.str; visible = false; readOnly = true; }; }; }; config = lib.mkIf cfg.enable { sops.secrets.wg-home-private-key = { sopsFile = builtins.path { path = "${toString ./.}/../../machines/${config.networking.hostName}/secrets.yaml"; }; }; sbruder.wireguard.home.address = peers."${config.networking.hostName}".address; networking.wireguard.interfaces.wg-home = { privateKeyFile = config.sops.secrets.wg-home-private-key.path; ips = [ "${cfg.address}/24" ]; listenPort = if enableServer then 51820 else null; peers = if enableServer then map (peerConfig: with peerConfig; { allowedIPs = [ "${address}/32" ]; inherit publicKey; }) (lib.attrValues (lib.filterAttrs (n: v: n != config.networking.hostName) peers)) else [ { allowedIPs = [ "10.80.0.0/24" ]; publicKey = peers."${serverHostName}".publicKey; endpoint = "${serverHostName}.sbruder.de:51820"; persistentKeepalive = 25; } ]; }; networking.firewall = { trustedInterfaces = [ "wg-home" ]; allowedUDPPorts = lib.optionals enableServer [ 51820 53 ]; }; boot.kernel.sysctl = lib.optionalAttrs enableServer { "net.ipv4.ip_forward" = 1; }; services.bind = lib.mkIf enableServer { enable = true; zones = lib.singleton { name = "vpn.sbruder.de"; file = let # !!! very hacky hexStringToInt = hex: (builtins.fromTOML "int = 0x${hex}").int; peerRecords = lib.concatStrings (lib.mapAttrsToList (peer: peerConfig: '' ${peer} IN A ${peerConfig.address} '') peers); peerRecordsHash = builtins.hashString "sha256" peerRecords; serial = hexStringToInt (lib.substring 0 8 peerRecordsHash); in pkgs.writeText "vpn.sbruder.de.zone" ('' $TTL 3600 @ IN SOA ${serverHostName}.sbruder.de. hostmaster.sbruder.de. ${toString serial} 28800 3600 604800 3600 @ IN NS ${serverHostName}.sbruder.de. '' + peerRecords); }; }; }; }