# The VPN: plain NixOS WireGuard, one interface `wg0`, a full mesh built from # ./mesh.nix. Identical on every host; the host's own entry is picked by # `networking.hostName`. { config, lib, ... }: let mesh = import ./mesh.nix; self = config.networking.hostName; in { networking.wireguard.interfaces.wg0 = { ips = [ "${mesh.${self}.address}/24" ]; listenPort = 51820; # Created on the host by `wg genkey`, never in the store. privateKeyFile = "/etc/wireguard/wg0.key"; peers = lib.mapAttrsToList (_: peer: { inherit (peer) publicKey endpoint; allowedIPs = [ "${peer.address}/32" ]; persistentKeepalive = 25; }) (removeAttrs mesh [ self ]); }; # The handshake arrives on the public interface. networking.firewall.allowedUDPPorts = [ config.networking.wireguard.interfaces.wg0.listenPort ]; }