diff --git a/hosts.nix b/hosts.nix index e467c8e..503a62f 100644 --- a/hosts.nix +++ b/hosts.nix @@ -115,29 +115,13 @@ with lib; wireguardKey = "birdLVh8roeZpcVo308Ums4l/aibhAxbi7MBsglkJyA="; }; - kalessin = { - hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOPt3iSSmgnlsv1/jafgZgI7o8UuXzcAL45hID2ThfS8 root@kalessin"; - endpoint = "kalessin.birdsong.network"; - ipv4 = "10.127.1.3"; - ipv6 = "fd70:81ca:0f8f:1::3"; - wireguardKey = "9vyIoXuu1UVjV+aFeuX9LoHRBeAAsiHbrLmYQY4nsQQ="; - }; - - reese = { - hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPd0qGxvcMLDwX1bqYpwOUL5c/CIgBllMFr+bGkwiwAn root@reese"; - endpoint = "reese.internetcat.org"; - ipv4 = "10.127.1.5"; - ipv6 = "fd70:81ca:0f8f:1::5"; - wireguardKey = "K/wArdwedMwjQULPOjOrPoEwsevaRhBZ3rUrH7pNWHM="; - }; - - bear = { - hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIZ9Kn1CIcDHaleKHf7zO6O30Rbxs/FwL0/Ie+mEjZJr root@bear"; - endpoint = "bear.internetcat.org"; - ipv4 = "10.127.1.6"; - ipv6 = "fd70:81ca:0f8f:1::6"; - wireguardKey = "mXWQo1Vn2YFr7OhFNc3g7Zbcf/qnwuLx8HHCn6HKwBc="; - }; + # kalessin = { + # # hostKey = ""; + # endpoint = "kalessin.birdsong.network"; + # ipv4 = "10.127.1.3"; + # ipv6 = "fd70:81ca:0f8f:1::3"; + # # wireguardKey = ""; + # }; tohru = { hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOk8wuGzF0Y7SaH9aimo3SmCz99MTQwL+rEVhx0jsueU root@tohru"; @@ -148,39 +132,14 @@ with lib; wireguardKey = "lk3PCQM1jmZoI8sM/rWSyKNuZOUnjox3n9L9geJD+18="; }; - groves = { - hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPQNZ/Q+x7mDYfYXftpZpWkfPByyMBbYmVFobM4vSDW2 root@groves"; - subnet = "roaming"; - ipv4 = "10.127.2.2"; - ipv6 = "fd70:81ca:0f8f:2::2"; - wireguardKey = "Tsbw77gIsoa3eBWZpQwZAM6EPpq+7yS33qoFHS4tXlY="; - }; - - carter = { - hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEHHHYG6A995Po05+JXQsvB79ZoIiSOJnW6AiJgVYPic root@carter"; - subnet = "roaming"; - ipv4 = "10.127.2.3"; - ipv6 = "fd70:81ca:0f8f:2::3"; - wireguardKey = "bJVSqLNtcRsZH3fki9sZ8TofgKd8JgRf7z/oHzUjMGk="; - }; - - kilgharrah = { - hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOgGF3gzzlMbxxk3UAAgHJ7sDdjqtrw7UW16M1XhXtz2 root@kilgharrah"; - subnet = "weyrhold"; - endpoint = "192.168.2.1"; - ipv4 = "10.127.3.1"; - ipv6 = "fd70:81ca:0f8f:3::1"; - wireguardKey = "LXQVU0MFKVO/mml5krHnf6NcL4GxF6XFJmvpmjrLBFA="; - }; - - elucredassa = { - hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+Y/vqGNc1wXUAg4XMAAcLupkggywj2LpYDwA16ONbH root@elucredassa"; - subnet = "weyrhold"; - endpoint = "192.168.2.2"; - ipv4 = "10.127.3.2"; - ipv6 = "fd70:81ca:0f8f:3::2"; - wireguardKey = "hwgf4efFNOtQwCDMpZI4uyPDjzPzHF056pWgobGaxRY="; - }; + # kilgharrah = { + # # hostKey = ""; + # subnet = "weyrhold"; + # endpoint = "192.168.2.1"; + # ipv4 = "10.127.3.1"; + # ipv6 = "fd70:81ca:0f8f:3::1"; + # # wireguardKey = ""; + # }; shaw = { hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMC0AomCZZiUV/BCpImiV4p/vGvFaz5QNc+fJLXmS5p root@shaw"; diff --git a/peering.nix b/peering.nix index 4fee698..01a4983 100644 --- a/peering.nix +++ b/peering.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, ... }: +with lib; let - inherit (lib) types mkIf mkMerge mkOption mkEnableOption optionals filterAttrs mapAttrsToList; cfg = config.birdsong.peering; hostName = if null != cfg.hostName then cfg.hostName else config.networking.hostName; hosts = config.birdsong.hosts; @@ -30,28 +30,22 @@ in description = "Whether to automatically open firewall ports."; type = types.bool; }; - privateKeyFile = mkOption { - default = null; + privateKey = mkOption { description = '' - Path to the private key for this peer, as generated by - {command}`wg genkey`. Must be readable by the user "systemd-network"; - systemd.netdev(5) recommends it be owned by "root:systemd-network" with - a "0640" file mode. Set exactly one of this or - {option}`birdsong.peering.privateKeyCredential`. + Private key for this peer, as generated by `wg genkey`. For security, + it is recommended to use {option}`birdsong.peering.privateKeyFile` + instead, or use `@`-syntax to read a systemd credential; see + systemd.netdev(5) for more details. ''; - type = with types; nullOr str; + type = types.str; }; - privateKeyCredential = mkOption { - default = null; + privateKeyFile = mkOption { description = '' - Name of a systemd credential containing a private key for this peer, as - generated by {command}`wg genkey`. Set exactly one of this or - {option}`birdsong.peering.privateKeyFile`. - - To load the credential from an encrypted credential file, set - {option}`systemd.services.systemd-networkd.serviceConfig.LoadCredentialEncrypted`. + Path to the private key for this peer, as generated by `wg genkey`. Must + be readable by the user "systemd-network"; see systemd.netdev(5) for + more details. ''; - type = with types; nullOr str; + type = types.path; }; persistentKeepalive = mkOption { default = 0; @@ -75,8 +69,8 @@ in message = "birdsong depends on networkd. systemd.network.enable must be true"; } { - assertion = (cfg.privateKeyCredential != null && cfg.privateKeyFile == null) || (cfg.privateKeyFile != null && cfg.privateKeyCredential == null); - message = "exactly one of birdsong.peering.privateKeyCredential or birdsong.peering.privateKeyFile must be set"; + assertion = cfg ? privateKey || cfg ? privateKeyFile; + message = "birdsong.peering.privateKey or birdsong.peering.privateKeyFile must be set"; } { assertion = hostName != null; @@ -92,38 +86,34 @@ in networking.firewall.allowedUDPPorts = mkIf cfg.openPorts [ host.port ]; systemd.network = { + enable = true; + netdevs."30-birdsong" = { netdevConfig = { Name = cfg.interface; Kind = "wireguard"; Description = "wireguard tunnel to the birdsong network"; }; - - wireguardConfig = mkMerge [ - { - ListenPort = host.port; - } - (mkIf (cfg.privateKeyCredential != null) { - PrivateKey = "@${cfg.privateKeyCredential}"; - }) - (mkIf (cfg.privateKeyFile != null) { - PrivateKeyFile = cfg.privateKeyFile; - }) - ]; - + wireguardConfig = { + PrivateKey = mkIf (cfg ? privateKey) cfg.privateKey; + PrivateKeyFile = mkIf (cfg ? privateKeyFile) cfg.privateKeyFile; + ListenPort = host.port; + }; wireguardPeers = let canDirectPeer = host: peer: peer.subnet == "internet" || (host.subnet != "roaming" && peer.subnet == host.subnet); in mapAttrsToList (name: peer: { - PublicKey = peer.wireguardKey; - AllowedIPs = [ peer.ipv4 peer.ipv6 ] - ++ optionals peer.isRouter [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ]; - Endpoint = mkIf (canDirectPeer host peer) "${peer.endpoint}:${toString peer.port}"; - PersistentKeepalive = mkIf (peer.subnet != host.subnet) cfg.persistentKeepalive; + wireguardPeerConfig = { + PublicKey = peer.wireguardKey; + AllowedIPs = [ peer.ipv4 peer.ipv6 ] + ++ optionals peer.isRouter [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ]; + Endpoint = mkIf (canDirectPeer host peer) "${peer.endpoint}:${toString peer.port}"; + PersistentKeepalive = mkIf (peer.subnet != host.subnet) cfg.persistentKeepalive; + }; }) - (filterAttrs (name: peer: peer != host && (canDirectPeer host peer || canDirectPeer peer host)) hosts); + (filterAttrs (name: peer: peer != host && (host.subnet == "internet" || canDirectPeer host peer)) hosts); }; networks."30-birdsong" = { @@ -132,12 +122,5 @@ in ++ optionals host.isRouter [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ]; }; }; - - programs.ssh.knownHosts = lib.mapAttrs' - (name: host: lib.nameValuePair ("birdsong_" + name) { - publicKey = host.hostKey; - hostNames = [ host.ipv4 host.ipv6 ]; - }) - hosts; }; }