{ lib, pkgs, ... }: let inherit (pkgs) writeShellScriptBin; inherit (lib.lists) forEach; inherit (lib.strings) concatStringsSep optionalString; inherit (builtins) attrNames; wireguardData = import ../data/wireguard/chaosInternalWireGuard.nix; wireguardHosts = wireguardData.hosts; kvPathForHost = host: "/private-public-keys/wireguard/chaos-internal/${host}"; in rec { initAllScript = writeShellScriptBin "wg-keys-init-all" (let vault = "${pkgs.vault}/bin/vault"; in '' PUBKEYS_FILE=$1 if [ -z "$PUBKEYS_FILE" ]; then echo "please provide path to file with pubkeys" exit 1 fi ${concatStringsSep "\n" (forEach (attrNames wireguardHosts) (hostName: '' echo "{}" | ${vault} kv put "${kvPathForHost hostName}" - 2>/dev/null ''))} ${concatStringsSep "\n" (forEach (attrNames wireguardHosts) (hostName: '' echo "Deploying keys for ${hostName}" "${genInitScript hostName}/bin/wg-keys-init-${hostName}" "$PUBKEYS_FILE" ''))} ''); genInitScript = systemHostName: (writeShellScriptBin "wg-keys-init-${systemHostName}" (let vault = "${pkgs.vault}/bin/vault"; jq = "${pkgs.jq}/bin/jq"; wg = "${pkgs.wireguard-tools}/bin/wg"; sponge = "${pkgs.moreutils}/bin/sponge"; in '' PUBKEYS_FILE=$1 if [ -z "$PUBKEYS_FILE" ]; then echo "please provide path to file with pubkeys" exit 1 fi PRIVATE=$(${wg} genkey) PUBLIC=$(echo "$PRIVATE" | ${wg} pubkey) TMP_DIR=$(mktemp -d) pushd "$TMP_DIR" echo "{}" > currentHost.json ${jq} ".public = \"$PUBLIC\"" currentHost.json | ${sponge} currentHost.json ${jq} ".private = \"$PRIVATE\"" currentHost.json | ${sponge} currentHost.json cat currentHost.json | ${vault} kv put "${kvPathForHost systemHostName}" - 2>/dev/null cat currentHost.json | jq popd rm -rf "$TMP_DIR" ${jq} ".\"${systemHostName}\" = \"$PUBLIC\"" "$PUBKEYS_FILE" | ${sponge} "$PUBKEYS_FILE" '')); genConfScript = systemHostName: (writeShellScriptBin "wg-gen-conf-${systemHostName}" (let vault = "${pkgs.vault}/bin/vault"; jq = "${pkgs.jq}/bin/jq"; currentHostConfig = wireguardHosts.${systemHostName}; in '' set -euo pipefail getPrivateKey() { ${vault} kv get -format=json "/private-public-keys/wireguard/chaos-internal/$1" | ${jq} -r ".data.data.private" | tr -d '\n' } cat << EOF [interface] Address = ${currentHostConfig.ip}/24 ${optionalString (currentHostConfig ? "listenAddress") "ListenAddress = ${toString currentHostConfig.listenAddress}"} PrivateKey = $(getPrivateKey ${systemHostName}) ${concatStringsSep "\n" (forEach (attrNames wireguardHosts) (hostName: (let hostConfig = wireguardHosts.${hostName}; in '' [Peer] PublicKey = ${hostConfig.public} ${optionalString (hostConfig ? "endpoint") "Endpoint = ${hostConfig.endpoint}"} AllowedIPs = ${ if hostConfig ? "allowedIPs" then concatStringsSep "," hostConfig.allowedIPs else "${hostConfig.ip}/32" } '')))} EOF '')); }