Compare commits

..

1 commit

Author SHA1 Message Date
912341c1e1 add birdsong.peering.privateKey option 2024-11-05 17:31:54 +00:00
2 changed files with 44 additions and 102 deletions

View file

@ -115,29 +115,13 @@ with lib;
wireguardKey = "birdLVh8roeZpcVo308Ums4l/aibhAxbi7MBsglkJyA="; wireguardKey = "birdLVh8roeZpcVo308Ums4l/aibhAxbi7MBsglkJyA=";
}; };
kalessin = { # kalessin = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOPt3iSSmgnlsv1/jafgZgI7o8UuXzcAL45hID2ThfS8 root@kalessin"; # # hostKey = "";
endpoint = "kalessin.birdsong.network"; # endpoint = "kalessin.birdsong.network";
ipv4 = "10.127.1.3"; # ipv4 = "10.127.1.3";
ipv6 = "fd70:81ca:0f8f:1::3"; # ipv6 = "fd70:81ca:0f8f:1::3";
wireguardKey = "9vyIoXuu1UVjV+aFeuX9LoHRBeAAsiHbrLmYQY4nsQQ="; # # wireguardKey = "";
}; # };
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=";
};
tohru = { tohru = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOk8wuGzF0Y7SaH9aimo3SmCz99MTQwL+rEVhx0jsueU root@tohru"; hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOk8wuGzF0Y7SaH9aimo3SmCz99MTQwL+rEVhx0jsueU root@tohru";
@ -148,39 +132,14 @@ with lib;
wireguardKey = "lk3PCQM1jmZoI8sM/rWSyKNuZOUnjox3n9L9geJD+18="; wireguardKey = "lk3PCQM1jmZoI8sM/rWSyKNuZOUnjox3n9L9geJD+18=";
}; };
groves = { # kilgharrah = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPQNZ/Q+x7mDYfYXftpZpWkfPByyMBbYmVFobM4vSDW2 root@groves"; # # hostKey = "";
subnet = "roaming"; # subnet = "weyrhold";
ipv4 = "10.127.2.2"; # endpoint = "192.168.2.1";
ipv6 = "fd70:81ca:0f8f:2::2"; # ipv4 = "10.127.3.1";
wireguardKey = "Tsbw77gIsoa3eBWZpQwZAM6EPpq+7yS33qoFHS4tXlY="; # ipv6 = "fd70:81ca:0f8f:3::1";
}; # # wireguardKey = "";
# };
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=";
};
shaw = { shaw = {
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMC0AomCZZiUV/BCpImiV4p/vGvFaz5QNc+fJLXmS5p root@shaw"; hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMC0AomCZZiUV/BCpImiV4p/vGvFaz5QNc+fJLXmS5p root@shaw";

View file

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib;
let let
inherit (lib) types mkIf mkMerge mkOption mkEnableOption optionals filterAttrs mapAttrsToList;
cfg = config.birdsong.peering; cfg = config.birdsong.peering;
hostName = if null != cfg.hostName then cfg.hostName else config.networking.hostName; hostName = if null != cfg.hostName then cfg.hostName else config.networking.hostName;
hosts = config.birdsong.hosts; hosts = config.birdsong.hosts;
@ -30,28 +30,22 @@ in
description = "Whether to automatically open firewall ports."; description = "Whether to automatically open firewall ports.";
type = types.bool; type = types.bool;
}; };
privateKeyFile = mkOption { privateKey = mkOption {
default = null;
description = '' description = ''
Path to the private key for this peer, as generated by Private key for this peer, as generated by `wg genkey`. For security,
{command}`wg genkey`. Must be readable by the user "systemd-network"; it is recommended to use {option}`birdsong.peering.privateKeyFile`
systemd.netdev(5) recommends it be owned by "root:systemd-network" with instead, or use `@`-syntax to read a systemd credential; see
a "0640" file mode. Set exactly one of this or systemd.netdev(5) for more details.
{option}`birdsong.peering.privateKeyCredential`.
''; '';
type = with types; nullOr str; type = types.str;
}; };
privateKeyCredential = mkOption { privateKeyFile = mkOption {
default = null;
description = '' description = ''
Name of a systemd credential containing a private key for this peer, as Path to the private key for this peer, as generated by `wg genkey`. Must
generated by {command}`wg genkey`. Set exactly one of this or be readable by the user "systemd-network"; see systemd.netdev(5) for
{option}`birdsong.peering.privateKeyFile`. more details.
To load the credential from an encrypted credential file, set
{option}`systemd.services.systemd-networkd.serviceConfig.LoadCredentialEncrypted`.
''; '';
type = with types; nullOr str; type = types.path;
}; };
persistentKeepalive = mkOption { persistentKeepalive = mkOption {
default = 0; default = 0;
@ -75,8 +69,8 @@ in
message = "birdsong depends on networkd. systemd.network.enable must be true"; message = "birdsong depends on networkd. systemd.network.enable must be true";
} }
{ {
assertion = (cfg.privateKeyCredential != null && cfg.privateKeyFile == null) || (cfg.privateKeyFile != null && cfg.privateKeyCredential == null); assertion = cfg ? privateKey || cfg ? privateKeyFile;
message = "exactly one of birdsong.peering.privateKeyCredential or birdsong.peering.privateKeyFile must be set"; message = "birdsong.peering.privateKey or birdsong.peering.privateKeyFile must be set";
} }
{ {
assertion = hostName != null; assertion = hostName != null;
@ -92,38 +86,34 @@ in
networking.firewall.allowedUDPPorts = mkIf cfg.openPorts [ host.port ]; networking.firewall.allowedUDPPorts = mkIf cfg.openPorts [ host.port ];
systemd.network = { systemd.network = {
enable = true;
netdevs."30-birdsong" = { netdevs."30-birdsong" = {
netdevConfig = { netdevConfig = {
Name = cfg.interface; Name = cfg.interface;
Kind = "wireguard"; Kind = "wireguard";
Description = "wireguard tunnel to the birdsong network"; Description = "wireguard tunnel to the birdsong network";
}; };
wireguardConfig = {
wireguardConfig = mkMerge [ PrivateKey = mkIf (cfg ? privateKey) cfg.privateKey;
{ PrivateKeyFile = mkIf (cfg ? privateKeyFile) cfg.privateKeyFile;
ListenPort = host.port; ListenPort = host.port;
} };
(mkIf (cfg.privateKeyCredential != null) {
PrivateKey = "@${cfg.privateKeyCredential}";
})
(mkIf (cfg.privateKeyFile != null) {
PrivateKeyFile = cfg.privateKeyFile;
})
];
wireguardPeers = wireguardPeers =
let let
canDirectPeer = host: peer: peer.subnet == "internet" || (host.subnet != "roaming" && peer.subnet == host.subnet); canDirectPeer = host: peer: peer.subnet == "internet" || (host.subnet != "roaming" && peer.subnet == host.subnet);
in in
mapAttrsToList mapAttrsToList
(name: peer: { (name: peer: {
wireguardPeerConfig = {
PublicKey = peer.wireguardKey; PublicKey = peer.wireguardKey;
AllowedIPs = [ peer.ipv4 peer.ipv6 ] AllowedIPs = [ peer.ipv4 peer.ipv6 ]
++ optionals peer.isRouter [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ]; ++ optionals peer.isRouter [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ];
Endpoint = mkIf (canDirectPeer host peer) "${peer.endpoint}:${toString peer.port}"; Endpoint = mkIf (canDirectPeer host peer) "${peer.endpoint}:${toString peer.port}";
PersistentKeepalive = mkIf (peer.subnet != host.subnet) cfg.persistentKeepalive; 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" = { networks."30-birdsong" = {
@ -132,12 +122,5 @@ in
++ optionals host.isRouter [ "10.127.0.0/16" "fd70:81ca:0f8f::/48" ]; ++ 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;
}; };
} }