1
1
Fork 1
mirror of https://github.com/oddlama/nixos-extra-modules.git synced 2025-10-10 22:00:39 +02:00

chore: remove external peers from wireguard module

This commit is contained in:
oddlama 2025-01-25 15:04:00 +01:00
parent 2502ff50ab
commit 0660c722cf
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
2 changed files with 278 additions and 361 deletions

View file

@ -6,30 +6,18 @@ inputs: final: prev: let
attrValues
concatLists
concatMap
concatStringsSep
escapeShellArg
filter
flatten
flip
genAttrs
mapAttrs'
nameValuePair
partition
removeSuffix
warn
;
inherit
(final.lib)
net
concatAttrs
types
;
inherit
(final.lib.secrets)
rageDecryptArgs
;
in {
lib =
prev.lib
@ -66,15 +54,15 @@ in {
in "wireguard-${wgName}-psks-${peer1}+${peer2}";
# All nodes that are part of this network
participatingNodes =
filter
(n: builtins.hasAttr wgName nodes.${n}.config.wireguard)
(attrNames nodes);
participatingNodes = filter (n: builtins.hasAttr wgName nodes.${n}.config.wireguard) (
attrNames nodes
);
# Partition nodes by whether they are servers
_participatingNodes_isServerPartition =
partition
(n: (wgCfgOf n).server.host != null)
partition (
n: (wgCfgOf n).server.host != null
)
participatingNodes;
participatingServerNodes = _participatingNodes_isServerPartition.right;
@ -83,43 +71,26 @@ in {
# Maps all nodes that are part of this network to their addresses
nodePeers = genAttrs participatingNodes (n: (wgCfgOf n).addresses);
externalPeerName = p: "external-${p}";
# Only peers that are defined as externalPeers on the given node.
# Prepends "external-" to their name.
externalPeersForNode = node:
mapAttrs' (p: nameValuePair (externalPeerName p)) (wgCfgOf node).server.externalPeers;
# All peers that are defined as externalPeers on any node.
# Prepends "external-" to their name.
allExternalPeers = concatAttrs (map externalPeersForNode participatingNodes);
# All peers that are part of this network
allPeers = nodePeers // allExternalPeers;
# Concatenation of all external peer names names without any transformations.
externalPeerNamesRaw = concatMap (n: attrNames (wgCfgOf n).server.externalPeers) participatingNodes;
# A list of all occurring addresses.
usedAddresses =
concatMap (n: (wgCfgOf n).addresses) participatingNodes
++ flatten (concatMap (n: attrValues (wgCfgOf n).server.externalPeers) participatingNodes);
usedAddresses = concatMap (n: (wgCfgOf n).addresses) participatingNodes;
# A list of all occurring addresses, but only includes addresses that
# are not assigned automatically.
explicitlyUsedAddresses =
flip concatMap participatingNodes
(n:
filter (x: !types.isLazyValue x)
(concatLists
(nodes.${n}.options.wireguard.type.nestedTypes.elemType.getSubOptions (wgCfgOf n)).addresses.definitions))
++ flatten (concatMap (n: attrValues (wgCfgOf n).server.externalPeers) participatingNodes);
explicitlyUsedAddresses = flip concatMap participatingNodes (
n:
filter (x: !types.isLazyValue x) (
concatLists
(nodes.${n}.options.wireguard.type.nestedTypes.elemType.getSubOptions (wgCfgOf n))
.addresses
.definitions
)
);
# The cidrv4 and cidrv6 of the network spanned by all participating peer addresses.
# This also takes into account any reserved address ranges that should be part of the network.
networkAddresses =
net.cidr.merge (usedAddresses
++ concatMap (n: (wgCfgOf n).server.reservedAddresses) participatingServerNodes);
networkAddresses = net.cidr.merge (
usedAddresses ++ concatMap (n: (wgCfgOf n).server.reservedAddresses) participatingServerNodes
);
# The network spanning cidr addresses. The respective cidrv4 and cirdv6 are only
# included if they exist.
@ -127,29 +98,30 @@ in {
# The cidrv4 and cidrv6 of the network spanned by all reserved addresses only.
# Used to determine automatically assigned addresses first.
spannedReservedNetwork =
net.cidr.merge (concatMap (n: (wgCfgOf n).server.reservedAddresses) participatingServerNodes);
spannedReservedNetwork = net.cidr.merge (
concatMap (n: (wgCfgOf n).server.reservedAddresses) participatingServerNodes
);
# Assigns an ipv4 address from spannedReservedNetwork.cidrv4
# to each participant that has not explicitly specified an ipv4 address.
assignedIpv4Addresses = assert assertMsg
(spannedReservedNetwork.cidrv4 != null)
assignedIpv4Addresses = assert assertMsg (spannedReservedNetwork.cidrv4 != null)
"Wireguard network '${wgName}': At least one participating node must reserve a cidrv4 address via `reservedAddresses` so that ipv4 addresses can be assigned automatically from that network.";
net.cidr.assignIps
spannedReservedNetwork.cidrv4
net.cidr.assignIps spannedReservedNetwork.cidrv4
# Don't assign any addresses that are explicitly configured on other hosts
(filter (x: net.cidr.contains x spannedReservedNetwork.cidrv4) (filter net.ip.isv4 explicitlyUsedAddresses))
(filter (x: net.cidr.contains x spannedReservedNetwork.cidrv4) (
filter net.ip.isv4 explicitlyUsedAddresses
))
participatingNodes;
# Assigns an ipv6 address from spannedReservedNetwork.cidrv6
# to each participant that has not explicitly specified an ipv6 address.
assignedIpv6Addresses = assert assertMsg
(spannedReservedNetwork.cidrv6 != null)
assignedIpv6Addresses = assert assertMsg (spannedReservedNetwork.cidrv6 != null)
"Wireguard network '${wgName}': At least one participating node must reserve a cidrv6 address via `reservedAddresses` so that ipv6 addresses can be assigned automatically from that network.";
net.cidr.assignIps
spannedReservedNetwork.cidrv6
net.cidr.assignIps spannedReservedNetwork.cidrv6
# Don't assign any addresses that are explicitly configured on other hosts
(filter (x: net.cidr.contains x spannedReservedNetwork.cidrv6) (filter net.ip.isv6 explicitlyUsedAddresses))
(filter (x: net.cidr.contains x spannedReservedNetwork.cidrv6) (
filter net.ip.isv6 explicitlyUsedAddresses
))
participatingNodes;
# Appends / replaces the correct cidr length to the argument,
@ -160,45 +132,11 @@ in {
then networkAddresses.cidrv6
else networkAddresses.cidrv4;
in "${net.cidr.ip addr}/${toString (net.cidr.length relevantNetworkAddr)}";
# Creates a script that when executed outputs a wg-quick compatible configuration
# file for use with external peers. This is a script so we can access secrets without
# storing them in the nix-store.
wgQuickConfigScript = system: serverNode: extPeer: let
pkgs = userInputs.self.pkgs.${system};
snCfg = wgCfgOf serverNode;
peerName = externalPeerName extPeer;
addresses = map toNetworkAddr snCfg.server.externalPeers.${extPeer};
in
pkgs.writeShellScript "create-wg-conf-${wgName}-${serverNode}-${extPeer}" ''
privKey=$(${pkgs.rage}/bin/rage -d ${rageDecryptArgs} ${escapeShellArg (peerPrivateKeyPath peerName)}) \
|| { echo "error: Failed to decrypt!" >&2; exit 1; }
serverPsk=$(${pkgs.rage}/bin/rage -d ${rageDecryptArgs} ${escapeShellArg (peerPresharedKeyPath serverNode peerName)}) \
|| { echo "error: Failed to decrypt!" >&2; exit 1; }
cat <<EOF
[Interface]
Address = ${concatStringsSep ", " addresses}
PrivateKey = $privKey
[Peer]
PublicKey = ${removeSuffix "\n" (builtins.readFile (peerPublicKeyPath serverNode))}
PresharedKey = $serverPsk
AllowedIPs = ${concatStringsSep ", " networkCidrs}
Endpoint = ${snCfg.server.host}:${toString snCfg.server.port}
PersistentKeepalive = 25
EOF
'';
in {
inherit
allExternalPeers
allPeers
assignedIpv4Addresses
assignedIpv6Addresses
explicitlyUsedAddresses
externalPeerName
externalPeerNamesRaw
externalPeersForNode
networkAddresses
networkCidrs
nodePeers
@ -218,27 +156,23 @@ in {
toNetworkAddr
usedAddresses
wgCfgOf
wgQuickConfigScript
;
};
wireguard.createEvalCache = userInputs: wgNames:
genAttrs wgNames (wireguard.evaluateNetwork userInputs);
wireguard.createEvalCache = userInputs: wgNames: genAttrs wgNames (wireguard.evaluateNetwork userInputs);
wireguard.getNetwork = userInputs: wgName:
userInputs.self.wireguardEvalCache.${wgName}
or (
warn ''
The calculated information for the wireguard network "${wgName}" is not cached!
This will siginificantly increase evaluation times. Please consider pre-evaluating
this information by exposing it in your flake:
or (warn ''
The calculated information for the wireguard network "${wgName}" is not cached!
This will siginificantly increase evaluation times. Please consider pre-evaluating
this information by exposing it in your flake:
wireguardEvalCache = lib.wireguard.createEvalCache inputs [
"${wgName}"
# all other networks
];
wireguardEvalCache = lib.wireguard.createEvalCache inputs [
"${wgName}"
# all other networks
];
'' (wireguard.evaluateNetwork userInputs wgName)
);
'' (wireguard.evaluateNetwork userInputs wgName));
};
}