This commit is contained in:
Lucy Hochkamp 2025-09-17 09:02:08 +02:00
parent e986986e79
commit 53c7532351
No known key found for this signature in database
10 changed files with 131 additions and 107 deletions

View file

@ -6,6 +6,7 @@
instanceConfig,
...
}:
with lib;
let
wgServer = instanceConfig ? wg.server && instanceConfig.wg.server;
cfg = config.xyno.services.wireguard;
@ -19,33 +20,33 @@ let
prefix: hostName:
let
hostHash = builtins.hashString "sha512" hostName;
localParts = map (n: builtins.substring (n * 4) 4 hostHash) (lib.range 0 3);
localPart = lib.concatStringsSep ":" localParts;
localParts = map (n: builtins.substring (n * 4) 4 hostHash) (range 0 3);
localPart = concatStringsSep ":" localParts;
in
"${prefix}:${localPart}";
# peers list for networkd
filteredConfigs = builtins.filter (x: x.hostName != config.networking.hostName) (
lib.attrValues instanceConfigs
attrValues instanceConfigs
);
wgPeersLists = map (
c:
(
(lib.optional (c ? publicHostname) {
(optional (c ? publicHostname) {
# if peer is publicly on the internet
AllowedIPs =
(lib.optionals (c ? wg.server && c.wg.server) [
(optionals (c ? wg.server && c.wg.server) [
# is server
"::/0"
])
++ (lib.optionals (c ? wg.server && c.wg.server && c ? wg.v4 && instanceConfig ? wg.v4) [
++ (optionals (c ? wg.server && c.wg.server && c ? wg.v4 && instanceConfig ? wg.v4) [
# both client and server have a v4
"0.0.0.0/0"
])
++ (lib.optionals (!c ? wg.server || !c.wg.server) [
++ (optionals (!c ? wg.server || !c.wg.server) [
# is not server
"${genUlaForHost ulaPrefix c.hostName}/128" # if a host is reachable but shouldn't play server, send only to the hosts ip
])
++ (lib.optionals ((!c ? wg.server || !c.wg.server) && c ? wg.v4 && instanceConfig ? wg.v4) [
++ (optionals ((!c ? wg.server || !c.wg.server) && c ? wg.v4 && instanceConfig ? wg.v4) [
# no server, no ipv4 yay
"${c.wg.v4}/32"
]);
@ -55,13 +56,13 @@ let
PublicKey = c.wg.pubKey;
PresharedKeyFile = config.sops.secrets."wg/psk".path;
})
++ (lib.optional ((!c ? publicHostname) && wgServer && (c ? wg.pubKey)) {
++ (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"
]
++ (lib.optionals (c ? wg.v4 && instanceConfig ? wg.v4) [
++ (optionals (c ? wg.v4 && instanceConfig ? wg.v4) [
"${c.wg.v4}/32"
]);
PublicKey = c.wg.pubKey;
@ -69,43 +70,44 @@ let
})
)
) filteredConfigs;
wgPeers = lib.flatten wgPeersLists;
wgPeers = flatten wgPeersLists;
in
{
options.xyno.services.wireguard.enable = lib.mkEnableOption "enables wireguard";
options.xyno.services.wireguard.monHostsDomain = lib.mkOption {
type = lib.types.str;
options.xyno.services.wireguard.enable = mkEnableOption "enables wireguard";
options.xyno.services.wireguard.monHostsDomain = mkOption {
type = types.str;
default = "mon.wg.hailsatan.eu";
};
options.xyno.services.wireguard.hostsDomain = lib.mkOption {
type = lib.types.str;
options.xyno.services.wireguard.hostsDomain = mkOption {
type = types.str;
default = "wg.hailsatan.eu";
};
options.xyno.services.wireguard.ula = lib.mkOption {
type = lib.types.str;
options.xyno.services.wireguard.ula = mkOption {
type = types.str;
default = "fd68:b6a4:36e4";
};
options.xyno.services.wireguard.ip6 = lib.mkOption {
type = lib.types.str;
options.xyno.services.wireguard.ip6 = mkOption {
type = types.str;
default = genUlaForHost ulaPrefix config.networking.hostName;
};
options.xyno.services.wireguard.monIp6 = lib.mkOption {
type = lib.types.str;
options.xyno.services.wireguard.monIp6 = mkOption {
type = types.str;
default = genUlaForHost monitoringUlaPrefix config.networking.hostName;
};
config = lib.mkIf cfg.enable {
config = mkIf cfg.enable {
# TODO: add a all traffic through this network
networking.hosts =
(lib.mapAttrs' (n: v: {
value = [ "${v.hostName}.${cfg.hostsDomain}" ];
name = (genUlaForHost ulaPrefix v.hostName);
}) 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;
(mapAttrs' (
n: v: nameValuePair (genUlaForHost ulaPrefix v.hostName) [ "${v.hostName}.${cfg.hostsDomain}" ]
) instanceConfigs)
// (mapAttrs' (
n: v:
nameValuePair (genUlaForHost monitoringUlaPrefix v.hostName) [
"${v.hostName}.${cfg.monHostsDomain}"
]
) instanceConfigs);
networking.firewall.allowedUDPPorts = optional wgServer 51820;
networking.firewall.interfaces."wg0".allowedUDPPorts = optional wgServer 53;
systemd.network.netdevs."99-wg0" = {
netdevConfig = {
Name = "wg0";
@ -114,9 +116,9 @@ in
};
wireguardConfig = {
ListenPort = lib.mkIf wgServer 51820;
ListenPort = mkIf wgServer 51820;
PrivateKeyFile = config.sops.secrets."wg/privkey".path;
FirewallMark = "0x8888";
FirewallMark = 34952;
};
wireguardPeers = wgPeers;
};
@ -124,7 +126,7 @@ in
matchConfig.Name = "wg0";
networkConfig = {
Description = "xyno wireguard";
IPMasquerade = lib.mkIf (instanceConfig ? wg.server && instanceConfig.wg.server) "both";
IPMasquerade = mkIf (instanceConfig ? wg.server && instanceConfig.wg.server) "both";
IPv4Forwarding = (instanceConfig ? wg.server && instanceConfig.wg.server);
IPv6Forwarding = (instanceConfig ? wg.server && instanceConfig.wg.server);
};
@ -132,7 +134,7 @@ in
"${(genUlaForHost ulaPrefix config.networking.hostName)}/64"
"${(genUlaForHost monitoringUlaPrefix config.networking.hostName)}/64"
]
++ (lib.optionals (instanceConfig ? wg.v4) [ "${instanceConfig.wg.v4}/24" ]);
++ (optionals (instanceConfig ? wg.v4) [ "${instanceConfig.wg.v4}/24" ]);
};
systemd.network.networks."51-wg0-all-traffic" = {
matchConfig.Name = "wg0";
@ -144,7 +146,7 @@ in
};
routingPolicyRules = [
{
FirewallMark = "0x8888";
FirewallMark = 34952;
InvertRule = true;
Table = 1000;
Priority = 10;
@ -152,13 +154,13 @@ in
];
};
services.prometheus.exporters.wireguard =
lib.mkIf (wgServer && config.xyno.services.monitoring.enable)
mkIf (wgServer && config.xyno.services.monitoring.enable)
{
enable = true;
interfaces = [ "wg0" ];
};
services.coredns = lib.mkIf wgServer {
services.coredns = mkIf wgServer {
# for non nixos devices to be able to resolve vpn hostnames
enable = true;
config = ''
@ -170,9 +172,9 @@ in
}
'';
};
xyno.services.monitoring.exporters.coredns = lib.mkIf wgServer 9153;
xyno.services.monitoring.exporters.coredns = mkIf wgServer 9153;
xyno.services.monitoring.exporters.wireguard =
lib.mkIf wgServer config.services.prometheus.exporters.wireguard.port;
mkIf wgServer config.services.prometheus.exporters.wireguard.port;
sops.secrets."wg/privkey" = {
reloadUnits = [ "systemd-networkd.service" ];
sopsFile = ../../instances/${config.networking.hostName}/secrets/wg.yaml;