This commit is contained in:
Lucy Hochkamp 2025-08-26 00:58:27 +02:00
parent 414e830efa
commit d3a93fd115
No known key found for this signature in database
35 changed files with 1832 additions and 228 deletions

View file

@ -7,8 +7,9 @@
...
}:
let
wgServer = instanceConfig?wg.server && instanceConfig.wg.server;
cfg = config.xyno.services.wireguard;
ula = "fd68:b6a4:36e4";
ula = cfg.ula;
ulaPrefix = "${ula}:1337"; # /64 for normal vpn
monitoringUlaPrefix = "${ula}:2337"; # /64 for monitoring
@ -17,55 +18,84 @@ let
prefix: hostName:
let
hostHash = builtins.hashString "sha512" hostName;
localParts = map (n: builtins.substring (n * 4) 4 hostHash) hostHash;
localParts = map (n: builtins.substring (n * 4) 4 hostHash) (lib.range 0 3);
localPart = lib.concatStringsSep ":" localParts;
in
"${prefix}:${localPart}";
# peers list for networkd
wgPeers = map (
filteredConfigs = builtins.filter (x: x.hostName != config.networking.hostName ) (lib.attrValues instanceConfigs);
wgPeersLists = map (
c:
(
(lib.optionals (lib.hasAttr c "publicHostname") {
(lib.optional (c?publicHostname) {
# if peer is publicly on the internet
AllowedIPs =
(lib.optionals (c.wgServer) [
(lib.optionals (c.wg.server) [
"${ulaPrefix}::/48" # all traffic in the ula shall be sent to the server
])
++ (lib.optionals (!c.wgServer) [
++ (lib.optionals (!c.wg.server) [
"${genUlaForHost ulaPrefix c.hostName}/128" # if a host is reachable but shouldn't play server, send only to the hosts ip
]);
Endpoint = "${c.publicHostname}:51820";
PersistentKeepalive = 25;
PublicKey = c.wgPubKey;
})
++ (lib.optionals (!(lib.hasAttr c "publicHostname") && instanceConfig.wgServer && (lib.hasAttr c "wgPubKey")) {
# if this is the server and the peer isn't reachable on the internet
AllowedIPs = [
"${genUlaForHost ulaPrefix c.hostName}/128"
"${genUlaForHost monitoringUlaPrefix c.hostName}/128"
];
PublicKey = c.wgPubKey;
# TODO: preshared keys
PublicKey = c.wg.pubKey;
})
++ (lib.optional
((!c?publicHostname) && wgServer && (c?wg.pubKey))
{
# if this is the server and the peer isn't reachable on the internet
AllowedIPs = [
"${genUlaForHost ulaPrefix c.hostName}/128"
"${genUlaForHost monitoringUlaPrefix c.hostName}/128"
];
PublicKey = c.wg.pubKey;
PresharedKeyFile = config.sops.secrets."wg/psk".path; # TODO
}
)
)
) instanceConfigs;
) filteredConfigs;
wgPeers = lib.flatten wgPeersLists;
in
{
options.xyno.services.wireguard.enable = lib.mkEnableOption "enables wireguard";
options.xyno.services.wireguard.hostsDomain = lib.mkOpion { type = lib.types.str; default = "wg.hailsatan.eu"; };
options.xyno.services.wireguard.monHostsDomain = lib.mkOption {
type = lib.types.str;
default = "mon.wg.hailsatan.eu";
};
options.xyno.services.wireguard.hostsDomain = lib.mkOption {
type = lib.types.str;
default = "wg.hailsatan.eu";
};
options.xyno.services.wireguard.ula = lib.mkOption {
type = lib.types.str;
default = "fd68:b6a4:36e4";
};
options.xyno.services.wireguard.ip6 = lib.mkOption {
type = lib.types.str;
default = genUlaForHost ulaPrefix config.networking.hostName;
};
options.xyno.services.wireguard.monIp6 = lib.mkOption {
type = lib.types.str;
default = genUlaForHost monitoringUlaPrefix config.networking.hostName;
};
config = lib.mkIf cfg.enable {
xyno.services.monitoring.ip = genUlaForHost monitoringUlaPrefix config.networking.hostName;
networking.hosts = lib.mapAttrs' (
networking.hosts = (lib.mapAttrs' (
n: v: {
name = "${v.hostName}.${cfg.hostsDomain}";
value = [ (genUlaForHost ulaPrefix v.hostName) ];
value = ["${v.hostName}.${cfg.hostsDomain}"];
name = (genUlaForHost ulaPrefix v.hostName);
}
);
networking.firewall.allowedUDPPorts = lib.mkIf instanceConfig.wgServer [ 51820 ];
) instanceConfigs) // (lib.mapAttrs' (
n: v: {
value = ["${v.hostName}.${cfg.monHostsDomain}"];
name = (genUlaForHost monitoringUlaPrefix v.hostName);
}
) instanceConfigs);
networking.firewall.allowedUDPPorts = lib.optional wgServer [ 51820 ];
networking.firewall.interfaces."wg0".allowedUDPPorts = lib.optional wgServer [ 53 ];
systemd.network.netdevs."wg0" = {
wireguardConfig = {
ListenPort = lib.mkIf instanceConfig.wgServer 51820;
PrivateKeyFile = config.sops.secrets.wg_privkey.path; # TODO
ListenPort = lib.mkIf wgServer 51820;
PrivateKeyFile = config.sops.secrets."wg/privkey".path; # TODO
};
wireguardPeers = wgPeers;
};
@ -79,8 +109,28 @@ in
"${(genUlaForHost monitoringUlaPrefix config.networking.hostName)}/128"
];
};
services.prometheus.exporters.wireguard = lib.mkIf (wgServer && config.xyno.services.monitoring.enable) {
enable = true;
interfaces = [ "wg0" ];
};
sops.secrets.wg_privkey = {
services.coredns = lib.mkIf wgServer { # for non nixos devices to be able to resolve vpn hostnames
enable = true;
config = ''
. {
bind wg0
prometheus
hosts ${cfg.hostsDomain}
forward . /etc/resolv.conf
}
'';
};
xyno.services.monitoring.exporters.coredns = lib.mkIf wgServer 9153;
xyno.services.monitoring.exporters.wireguard = lib.mkIf wgServer config.services.prometheus.exporters.wireguard.port;
sops.secrets."wg/privkey" = {
reloadUnits = [ "systemd-networkd.service" ];
};
sops.secrets."wg/psk" = {
reloadUnits = [ "systemd-networkd.service" ];
};