chore: remove external peers from wireguard module
This commit is contained in:
parent
2502ff50ab
commit
0660c722cf
2 changed files with 278 additions and 361 deletions
|
@ -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 "[1;31merror:[m Failed to decrypt!" >&2; exit 1; }
|
||||
serverPsk=$(${pkgs.rage}/bin/rage -d ${rageDecryptArgs} ${escapeShellArg (peerPresharedKeyPath serverNode peerName)}) \
|
||||
|| { echo "[1;31merror:[m 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));
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue