services: wireguard: clean up logic
This module has a complicated logic, and I found the code quite ugly. making use of `mkMerge` makes it easier to read and think through.
This commit is contained in:
parent
84b61b25b3
commit
26eac86de0
|
@ -96,80 +96,100 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config.networking = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||||
wg-quick.interfaces."${cfg.iface}" = {
|
{
|
||||||
listenPort = cfg.port;
|
networking.wg-quick.interfaces."${cfg.iface}" = {
|
||||||
address = with cfg.net; with lib; [
|
listenPort = cfg.port;
|
||||||
"${v4.subnet}.${toString thisPeer.clientNum}/${toString v4.mask}"
|
address = with cfg.net; with lib; [
|
||||||
"${v6.subnet}::${toString thisPeer.clientNum}/${toHexString v6.mask}"
|
"${v4.subnet}.${toString thisPeer.clientNum}/${toString v4.mask}"
|
||||||
];
|
"${v6.subnet}::${toString thisPeer.clientNum}/${toHexString v6.mask}"
|
||||||
# Insecure, I don't care
|
];
|
||||||
privateKey = thisPeer.privateKey;
|
# Insecure, I don't care
|
||||||
|
privateKey = thisPeer.privateKey;
|
||||||
|
|
||||||
peers = lib.mapAttrsToList
|
peers =
|
||||||
(_: peer: {
|
let
|
||||||
inherit (peer) publicKey;
|
mkPeer = _: peer: lib.mkMerge [
|
||||||
} // lib.optionalAttrs thisPeerIsServer {
|
{
|
||||||
# Only forward from server to clients
|
inherit (peer) publicKey;
|
||||||
allowedIPs = with cfg.net; [
|
}
|
||||||
"${v4.subnet}.${toString peer.clientNum}/32"
|
|
||||||
"${v6.subnet}::${toString peer.clientNum}/128"
|
(lib.optionalAttrs thisPeerIsServer {
|
||||||
];
|
# Only forward from server to clients
|
||||||
} // lib.optionalAttrs (peer ? externalIp) {
|
allowedIPs = with cfg.net; [
|
||||||
# Known addresses
|
"${v4.subnet}.${toString peer.clientNum}/32"
|
||||||
endpoint = "${peer.externalIp}:${toString cfg.port}";
|
"${v6.subnet}::${toString peer.clientNum}/128"
|
||||||
} // lib.optionalAttrs (!thisPeerIsServer) {
|
];
|
||||||
# Forward all traffic to server
|
})
|
||||||
allowedIPs = with cfg.net; [
|
|
||||||
"0.0.0.0/0"
|
(lib.optionalAttrs (!thisPeerIsServer) {
|
||||||
"::/0"
|
# Forward all traffic through wireguard to server
|
||||||
];
|
allowedIPs = with cfg.net; [
|
||||||
# Roaming clients need to keep NAT-ing active
|
"0.0.0.0/0"
|
||||||
persistentKeepalive = 10;
|
"::/0"
|
||||||
})
|
];
|
||||||
otherPeers;
|
# Roaming clients need to keep NAT-ing active
|
||||||
} // lib.optionalAttrs thisPeerIsServer {
|
persistentKeepalive = 10;
|
||||||
# Setup forwarding on server
|
# We know that `peer` is a server, set up the endpoint
|
||||||
postUp = with cfg.net; ''
|
endpoint = "${peer.externalIp}:${toString cfg.port}";
|
||||||
${pkgs.iptables}/bin/iptables -A FORWARD -i ${cfg.iface} -j ACCEPT
|
})
|
||||||
${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s ${v4.subnet}.1/${toString v4.mask} -o ${extIface} -j MASQUERADE
|
];
|
||||||
${pkgs.iptables}/bin/ip6tables -A FORWARD -i ${cfg.iface} -j ACCEPT
|
in
|
||||||
${pkgs.iptables}/bin/ip6tables -t nat -A POSTROUTING -s ${v6.subnet}::1/${toString v6.mask} -o ${extIface} -j MASQUERADE
|
lib.mapAttrsToList mkPeer otherPeers;
|
||||||
'';
|
};
|
||||||
preDown = with cfg.net; ''
|
}
|
||||||
${pkgs.iptables}/bin/iptables -D FORWARD -i ${cfg.iface} -j ACCEPT
|
|
||||||
${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s ${v4.subnet}.1/${toString v4.mask} -o ${extIface} -j MASQUERADE
|
# Set up clients to use configured DNS servers
|
||||||
${pkgs.iptables}/bin/ip6tables -D FORWARD -i ${cfg.iface} -j ACCEPT
|
(lib.mkIf (!thisPeerIsServer) {
|
||||||
${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s ${v6.subnet}::1/${toString v6.mask} -o ${extIface} -j MASQUERADE
|
networking.wg-quick.interfaces."${cfg.iface}".dns =
|
||||||
'';
|
|
||||||
} // lib.optionalAttrs (!thisPeerIsServer) {
|
|
||||||
# Use DNS servers hosted on wireguard servers
|
|
||||||
dns =
|
|
||||||
let
|
let
|
||||||
isServer = _: peer: peer ? externalIp;
|
|
||||||
toInternalIps = peer: [
|
toInternalIps = peer: [
|
||||||
"${cfg.net.v4.subnet}.${toString peer.clientNum}"
|
"${cfg.net.v4.subnet}.${toString peer.clientNum}"
|
||||||
"${cfg.net.v6.subnet}::${toString peer.clientNum}"
|
"${cfg.net.v6.subnet}::${toString peer.clientNum}"
|
||||||
];
|
];
|
||||||
servers = lib.filterAttrs isServer otherPeers;
|
# We know that `otherPeers` is an attribute set of servers
|
||||||
internalIps = lib.flatten
|
internalIps = lib.flatten
|
||||||
(lib.mapAttrsToList (_: peer: toInternalIps peer) servers);
|
(lib.mapAttrsToList (_: peer: toInternalIps peer) otherPeers);
|
||||||
internalServers = lib.optionals cfg.dns.useInternal internalIps;
|
internalServers = lib.optionals cfg.dns.useInternal internalIps;
|
||||||
in
|
in
|
||||||
internalServers ++ cfg.dns.additionalServers;
|
internalServers ++ cfg.dns.additionalServers;
|
||||||
};
|
})
|
||||||
|
|
||||||
nat = lib.optionalAttrs thisPeerIsServer {
|
# Expose port
|
||||||
enable = true;
|
{
|
||||||
externalInterface = extIface;
|
networking.firewall.allowedUDPPorts = [ cfg.port ];
|
||||||
internalInterfaces = [ cfg.iface ];
|
}
|
||||||
};
|
|
||||||
|
|
||||||
firewall.allowedUDPPorts = [ cfg.port ];
|
# Allow NATing wireguard traffic on server
|
||||||
};
|
(lib.mkIf thisPeerIsServer {
|
||||||
|
networking.nat = {
|
||||||
|
enable = true;
|
||||||
|
externalInterface = extIface;
|
||||||
|
internalInterfaces = [ cfg.iface ];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
# Do not start the service by making it not wanted by any unit
|
# Set up forwarding to WAN
|
||||||
config.systemd.services.wg-quick-wg = lib.mkIf (!cfg.startAtBoot) {
|
(lib.mkIf thisPeerIsServer {
|
||||||
wantedBy = lib.mkForce [ ];
|
networking.wg-quick.interfaces."${cfg.iface}" = {
|
||||||
};
|
postUp = with cfg.net; ''
|
||||||
|
${pkgs.iptables}/bin/iptables -A FORWARD -i ${cfg.iface} -j ACCEPT
|
||||||
|
${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s ${v4.subnet}.1/${toString v4.mask} -o ${extIface} -j MASQUERADE
|
||||||
|
${pkgs.iptables}/bin/ip6tables -A FORWARD -i ${cfg.iface} -j ACCEPT
|
||||||
|
${pkgs.iptables}/bin/ip6tables -t nat -A POSTROUTING -s ${v6.subnet}::1/${toString v6.mask} -o ${extIface} -j MASQUERADE
|
||||||
|
'';
|
||||||
|
preDown = with cfg.net; ''
|
||||||
|
${pkgs.iptables}/bin/iptables -D FORWARD -i ${cfg.iface} -j ACCEPT
|
||||||
|
${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s ${v4.subnet}.1/${toString v4.mask} -o ${extIface} -j MASQUERADE
|
||||||
|
${pkgs.iptables}/bin/ip6tables -D FORWARD -i ${cfg.iface} -j ACCEPT
|
||||||
|
${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s ${v6.subnet}::1/${toString v6.mask} -o ${extIface} -j MASQUERADE
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
# When not needed at boot, ensure that there are no reverse dependencies
|
||||||
|
(lib.mkIf (!cfg.startAtBoot) {
|
||||||
|
systemd.services."wg-quick-${cfg.iface}".wantedBy = lib.mkForce [ ];
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue