feat: add wireguard key and psk generator app

This commit is contained in:
oddlama 2023-04-12 01:07:55 +02:00
parent b250a6b1b3
commit 6cffccd75c
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
4 changed files with 82 additions and 9 deletions

View file

@ -28,7 +28,9 @@
listenPort = 51822;
openFirewall = true;
externalPeers = {
test = ["10.0.0.91/32"];
test1 = ["10.0.0.91/32"];
test2 = ["10.0.0.92/32"];
test3 = ["10.0.0.93/32"];
};
};
}

View file

@ -49,18 +49,18 @@
};
configForNetwork = wgName: wg: let
peerPublicKey = peerName: builtins.readFile (../secrets/wireguard + "/${wgName}/${peerName}.pub");
peerPrivateKeyFile = peerName: ../secrets/wireguard + "/${wgName}/${peerName}.priv.age";
peerPrivateKeySecret = peerName: "wireguard-${wgName}-${peerName}.priv";
peerPublicKey = peerName: builtins.readFile (../secrets/wireguard + "/${wgName}/keys/${peerName}.pub");
peerPrivateKeyFile = peerName: ../secrets/wireguard + "/${wgName}/keys/${peerName}.age";
peerPrivateKeySecret = peerName: "wireguard-${wgName}-priv-${peerName}";
peerPresharedKeyFile = peerA: peerB: let
inherit (sortedPeers peerA peerB) peer1 peer2;
in
../secrets/wireguard + "/${wgName}/${peer1}-${peer2}.psk.age";
../secrets/wireguard + "/${wgName}/psks/${peer1}-${peer2}.age";
peerPresharedKeySecret = peerA: peerB: let
inherit (sortedPeers peerA peerB) peer1 peer2;
in "wireguard-${wgName}-${peer1}-${peer2}.psk";
in "wireguard-${wgName}-psks-${peer1}-${peer2}";
# All peers that are other nodes
nodesWithThisNetwork = filter (n: builtins.hasAttr wgName nodes.${n}.config.extra.wireguard.networks) (attrNames nodes);

View file

@ -3,9 +3,80 @@
pkgs,
...
}: let
inherit (pkgs.lib) escapeShellArg;
inherit
(pkgs.lib)
attrNames
concatMap
concatMapStrings
concatStringsSep
escapeShellArg
filter
substring
unique
;
isAbsolutePath = x: substring 0 1 x == "/";
masterIdentityArgs = concatMapStrings (x: ''-i ${escapeShellArg x} '') self.secrets.masterIdentities;
extraEncryptionPubkeys =
concatMapStrings (
x:
if isAbsolutePath x
then ''-R ${escapeShellArg x} ''
else ''-r ${escapeShellArg x} ''
)
self.secrets.extraEncryptionPubkeys;
sortedPeers = peerA: peerB:
if peerA < peerB
then {
peer1 = peerA;
peer2 = peerB;
}
else {
peer1 = peerB;
peer2 = peerA;
};
nodeNames = attrNames self.nodes;
nodesWithNet = wgName: filter (n: builtins.hasAttr wgName self.nodes.${n}.config.extra.wireguard.networks) nodeNames;
wireguardNetworks = unique (concatMap (n: attrNames self.nodes.${n}.config.extra.wireguard.networks) nodeNames);
externalPeersForNet = wgName: concatMap (n: attrNames self.nodes.${n}.config.extra.wireguard.networks.${wgName}.externalPeers) (nodesWithNet wgName);
externalPeers = wgName: concatMap (n: attrNames self.nodes.${n}.config.extra.wireguard.networks.${wgName}.externalPeers) (nodesWithNet wgName);
peers = wgName: nodesWithNet wgName ++ externalPeers wgName;
peerKeyBasename = wgName: peerName: "./secrets/wireguard/${wgName}/keys/${peerName}";
generatePeerKeys = wgName: peerName: let
keyBasename = peerKeyBasename wgName peerName;
privkeyFile = escapeShellArg "${keyBasename}.age";
pubkeyFile = escapeShellArg "${keyBasename}.pub";
in ''
if [[ ! -e ${privkeyFile} ]] || [[ ! -e ${pubkeyFile} ]]; then
mkdir -p $(dirname ${privkeyFile})
echo "Generating "${escapeShellArg keyBasename}".{age,pub}"
privkey=$(${pkgs.wireguard-tools}/bin/wg genkey)
echo "$privkey" | ${pkgs.wireguard-tools}/bin/wg pubkey > ${pubkeyFile}
${pkgs.rage}/bin/rage -e ${masterIdentityArgs} ${extraEncryptionPubkeys} <<< "$privkey" > ${pubkeyFile} \
|| { echo "error: Failed to encrypt wireguard private key for peer ${peerName} on network ${wgName}!" >&2; exit 1; }
fi
'';
generatePeerPsks = wgName: nodePeerName:
concatStringsSep "\n" (map (peerName: let
inherit (sortedPeers nodePeerName peerName) peer1 peer2;
pskFile = "./secrets/wireguard/${wgName}/psks/${peer1}-${peer2}.age";
in ''
if [[ ! -e ${pskFile} ]]; then
mkdir -p $(dirname ${pskFile})
echo "Generating "${pskFile}""
psk=$(${pkgs.wireguard-tools}/bin/wg genpsk)
${pkgs.rage}/bin/rage -e ${masterIdentityArgs} ${extraEncryptionPubkeys} <<< "$psk" > ${pskFile} \
|| { echo "error: Failed to encrypt wireguard psk for peers ${peer1} and ${peer2} on network ${wgName}!" >&2; exit 1; }
fi
'') (filter (x: x != nodePeerName) (peers wgName)));
in
pkgs.writeShellScript "generate-wireguard-keys" ''
set -euo pipefail
echo TODO
${concatStringsSep "\n" (concatMap (wgName: map (generatePeerKeys wgName) (peers wgName)) wireguardNetworks)}
${concatStringsSep "\n" (concatMap (wgName: map (generatePeerPsks wgName) (nodesWithNet wgName)) wireguardNetworks)}
''

View file

@ -22,5 +22,5 @@ in
# TODO generate "classic" config and run qrencode
pkgs.writeShellScript "show-wireguard-qr" ''
set -euo pipefail
echo ${concatStringsSep " " (map (x: "${x.net}.${x.peer}") externalPeers)} | fzf
echo ${escapeShellArg (concatStringsSep "\n" (map (x: "${x.net}.${x.peer}") externalPeers))} | fzf
''