88 lines
2.9 KiB
Nix
88 lines
2.9 KiB
Nix
{
|
|
pkgs,
|
|
lib,
|
|
config,
|
|
instanceConfigs,
|
|
instanceConfig,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.xyno.services.wireguard;
|
|
ula = "fd68:b6a4:36e4";
|
|
ulaPrefix = "${ula}:1337"; # /64 for normal vpn
|
|
monitoringUlaPrefix = "${ula}:2337"; # /64 for monitoring
|
|
|
|
# uses a hash digest as the host identifier
|
|
genUlaForHost =
|
|
prefix: hostName:
|
|
let
|
|
hostHash = builtins.hashString "sha512" hostName;
|
|
localParts = map (n: builtins.substring (n * 4) 4 hostHash) hostHash;
|
|
localPart = lib.concatStringsSep ":" localParts;
|
|
in
|
|
"${prefix}:${localPart}";
|
|
# peers list for networkd
|
|
wgPeers = map (
|
|
c:
|
|
(
|
|
(lib.optionals (lib.hasAttr c "publicHostname") {
|
|
# if peer is publicly on the internet
|
|
AllowedIPs =
|
|
(lib.optionals (c.wgServer) [
|
|
"${ulaPrefix}::/48" # all traffic in the ula shall be sent to the server
|
|
])
|
|
++ (lib.optionals (!c.wgServer) [
|
|
"${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
|
|
})
|
|
)
|
|
) instanceConfigs;
|
|
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"; };
|
|
config = lib.mkIf cfg.enable {
|
|
xyno.services.monitoring.ip = genUlaForHost monitoringUlaPrefix config.networking.hostName;
|
|
networking.hosts = lib.mapAttrs' (
|
|
n: v: {
|
|
name = "${v.hostName}.${cfg.hostsDomain}";
|
|
value = [ (genUlaForHost ulaPrefix v.hostName) ];
|
|
}
|
|
);
|
|
networking.firewall.allowedUDPPorts = lib.mkIf instanceConfig.wgServer [ 51820 ];
|
|
systemd.network.netdevs."wg0" = {
|
|
wireguardConfig = {
|
|
ListenPort = lib.mkIf instanceConfig.wgServer 51820;
|
|
PrivateKeyFile = config.sops.secrets.wg_privkey.path; # TODO
|
|
};
|
|
wireguardPeers = wgPeers;
|
|
};
|
|
systemd.network.networks."wg0" = {
|
|
matchConfig.Name = "wg0";
|
|
networkConfig = {
|
|
Description = "xyno wireguard";
|
|
};
|
|
address = [
|
|
"${(genUlaForHost ulaPrefix config.networking.hostName)}/128"
|
|
"${(genUlaForHost monitoringUlaPrefix config.networking.hostName)}/128"
|
|
];
|
|
};
|
|
|
|
sops.secrets.wg_privkey = {
|
|
reloadUnits = [ "systemd-networkd.service" ];
|
|
};
|
|
|
|
};
|
|
}
|