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,8 +96,9 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
config.networking = lib.mkIf cfg.enable {
|
||||
wg-quick.interfaces."${cfg.iface}" = {
|
||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
networking.wg-quick.interfaces."${cfg.iface}" = {
|
||||
listenPort = cfg.port;
|
||||
address = with cfg.net; with lib; [
|
||||
"${v4.subnet}.${toString thisPeer.clientNum}/${toString v4.mask}"
|
||||
|
@ -106,30 +107,71 @@ in
|
|||
# Insecure, I don't care
|
||||
privateKey = thisPeer.privateKey;
|
||||
|
||||
peers = lib.mapAttrsToList
|
||||
(_: peer: {
|
||||
peers =
|
||||
let
|
||||
mkPeer = _: peer: lib.mkMerge [
|
||||
{
|
||||
inherit (peer) publicKey;
|
||||
} // lib.optionalAttrs thisPeerIsServer {
|
||||
}
|
||||
|
||||
(lib.optionalAttrs thisPeerIsServer {
|
||||
# Only forward from server to clients
|
||||
allowedIPs = with cfg.net; [
|
||||
"${v4.subnet}.${toString peer.clientNum}/32"
|
||||
"${v6.subnet}::${toString peer.clientNum}/128"
|
||||
];
|
||||
} // lib.optionalAttrs (peer ? externalIp) {
|
||||
# Known addresses
|
||||
endpoint = "${peer.externalIp}:${toString cfg.port}";
|
||||
} // lib.optionalAttrs (!thisPeerIsServer) {
|
||||
# Forward all traffic to server
|
||||
})
|
||||
|
||||
(lib.optionalAttrs (!thisPeerIsServer) {
|
||||
# Forward all traffic through wireguard to server
|
||||
allowedIPs = with cfg.net; [
|
||||
"0.0.0.0/0"
|
||||
"::/0"
|
||||
];
|
||||
# Roaming clients need to keep NAT-ing active
|
||||
persistentKeepalive = 10;
|
||||
# We know that `peer` is a server, set up the endpoint
|
||||
endpoint = "${peer.externalIp}:${toString cfg.port}";
|
||||
})
|
||||
otherPeers;
|
||||
} // lib.optionalAttrs thisPeerIsServer {
|
||||
# Setup forwarding on server
|
||||
];
|
||||
in
|
||||
lib.mapAttrsToList mkPeer otherPeers;
|
||||
};
|
||||
}
|
||||
|
||||
# Set up clients to use configured DNS servers
|
||||
(lib.mkIf (!thisPeerIsServer) {
|
||||
networking.wg-quick.interfaces."${cfg.iface}".dns =
|
||||
let
|
||||
toInternalIps = peer: [
|
||||
"${cfg.net.v4.subnet}.${toString peer.clientNum}"
|
||||
"${cfg.net.v6.subnet}::${toString peer.clientNum}"
|
||||
];
|
||||
# We know that `otherPeers` is an attribute set of servers
|
||||
internalIps = lib.flatten
|
||||
(lib.mapAttrsToList (_: peer: toInternalIps peer) otherPeers);
|
||||
internalServers = lib.optionals cfg.dns.useInternal internalIps;
|
||||
in
|
||||
internalServers ++ cfg.dns.additionalServers;
|
||||
})
|
||||
|
||||
# Expose port
|
||||
{
|
||||
networking.firewall.allowedUDPPorts = [ cfg.port ];
|
||||
}
|
||||
|
||||
# Allow NATing wireguard traffic on server
|
||||
(lib.mkIf thisPeerIsServer {
|
||||
networking.nat = {
|
||||
enable = true;
|
||||
externalInterface = extIface;
|
||||
internalInterfaces = [ cfg.iface ];
|
||||
};
|
||||
})
|
||||
|
||||
# Set up forwarding to WAN
|
||||
(lib.mkIf thisPeerIsServer {
|
||||
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
|
||||
|
@ -142,34 +184,12 @@ in
|
|||
${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
|
||||
'';
|
||||
} // lib.optionalAttrs (!thisPeerIsServer) {
|
||||
# Use DNS servers hosted on wireguard servers
|
||||
dns =
|
||||
let
|
||||
isServer = _: peer: peer ? externalIp;
|
||||
toInternalIps = peer: [
|
||||
"${cfg.net.v4.subnet}.${toString peer.clientNum}"
|
||||
"${cfg.net.v6.subnet}::${toString peer.clientNum}"
|
||||
];
|
||||
servers = lib.filterAttrs isServer otherPeers;
|
||||
internalIps = lib.flatten
|
||||
(lib.mapAttrsToList (_: peer: toInternalIps peer) servers);
|
||||
internalServers = lib.optionals cfg.dns.useInternal internalIps;
|
||||
in
|
||||
internalServers ++ cfg.dns.additionalServers;
|
||||
};
|
||||
})
|
||||
|
||||
nat = lib.optionalAttrs thisPeerIsServer {
|
||||
enable = true;
|
||||
externalInterface = extIface;
|
||||
internalInterfaces = [ cfg.iface ];
|
||||
};
|
||||
|
||||
firewall.allowedUDPPorts = [ cfg.port ];
|
||||
};
|
||||
|
||||
# Do not start the service by making it not wanted by any unit
|
||||
config.systemd.services.wg-quick-wg = lib.mkIf (!cfg.startAtBoot) {
|
||||
wantedBy = lib.mkForce [ ];
|
||||
};
|
||||
# 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