diff --git a/README.md b/README.md index 6b1b7c0..52932f5 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,16 @@ type subnet = { }; ``` +! WARNING ! If your subnet name has a ".", the wireguard connection's name will +be everything preceding the ".". This is because there is a hard limit of 15 +characters for wireguard connection names. For example, if your subnet is named +"myVPN.mydomain.com" (18 characters), the wireguard connection will be named +"myVPN". This is useful because the longer name will still be used to generate +a unique ip and in the hosts file, just not for the netdev name. This +unfortunately means that you cannot share subdomains across different domain +on the same machine. A workaround is to use dashes if your FQDN is under 15 +characters. + ## Group: ```typescript type group = { diff --git a/configurers/networkd.nix b/configurers/networkd.nix index 984a86a..29f4e5f 100644 --- a/configurers/networkd.nix +++ b/configurers/networkd.nix @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -{lib, ...}@inputs: keyProviders: intermediateConfig: peerName: +{lib, ...}@inputs: keyProviders: intermediateConfig: localPeerName: with lib.trivial; with lib.attrsets; with lib.lists; @@ -11,31 +11,32 @@ with lib; with builtins; with import ../lib.nix; let - thisPeer = intermediateConfig.peers."${peerName}"; + thisPeer = intermediateConfig.peers."${localPeerName}"; # these aren't really important, I just wanted to reverse the argument order forEachAttr' = flip mapAttrs'; forEachAttrToList = flip mapAttrsToList; + shortName = fqdn: head (strings.splitString "." fqdn); in -with getKeyProviderFuncs keyProviders inputs intermediateConfig peerName; +with getKeyProviderFuncs keyProviders inputs intermediateConfig localPeerName; { networking.extraHosts = concatStringsSep "\n" (concatLists ( concatLists (forEachAttrToList thisPeer.subnetConnections (subnetName: subnetConnection: - forEachAttrToList subnetConnection.peerConnections (otherPeerName: peerConnection: forEach peerConnection.ipAddresses (ip: "${strings.removeSuffix "/64" ip} ${otherPeerName}.${subnetName}")) + forEachAttrToList subnetConnection.peerConnections (remotePeerName: peerConnection: forEach peerConnection.ipAddresses (ip: "${strings.removeSuffix "/64" ip} ${remotePeerName}.${subnetName}")) )))); systemd.network = { - netdevs = forEachAttr' thisPeer.subnetConnections (subnetName: subnetConnection: nameValuePair "50-wn-${subnetName}" { + netdevs = forEachAttr' thisPeer.subnetConnections (subnetName: subnetConnection: nameValuePair "50-${shortName subnetName}" { netdevConfig = { Kind = "wireguard"; - Name = "wn-${subnetName}"; + Name = "${shortName subnetName}"; }; wireguardConfig = { PrivateKeyFile = getPrivKeyFile; ListenPort = subnetConnection.listenPort; }; - wireguardPeers = forEachAttrToList subnetConnection.peerConnections (otherPeerName: peerConnection: { + wireguardPeers = forEachAttrToList subnetConnection.peerConnections (remotePeerName: peerConnection: { wireguardPeerConfig = { Endpoint = "${peerConnection.endpoint.ip}:${builtins.toString peerConnection.endpoint.port}"; - PublicKey = getPeerPubKey otherPeerName; - AllowedIPs = peerConnection.ipAddresses; + PublicKey = getPeerPubKey remotePeerName; + AllowedIPs = map (ip: cidr2ip ip + "/128") peerConnection.ipAddresses; PresharedKeyFile = getSubnetPSKFile subnetName; }; } @@ -44,8 +45,8 @@ with getKeyProviderFuncs keyProviders inputs intermediateConfig peerName; // (warnIf (peerConnection.endpoint ? dynamicEndpointRefreshRestartSeconds) "dynamicEndpointRefreshRestartSeconds not supported for networkd" {}) ); }); - networks = forEachAttr' thisPeer.subnetConnections (subnetName: subnetConnection: nameValuePair "${subnetName}" { - matchConfig.Name = "wn-${subnetName}"; + networks = forEachAttr' thisPeer.subnetConnections (subnetName: subnetConnection: nameValuePair "50-${shortName subnetName}" { + matchConfig.Name = "${shortName subnetName}"; address = subnetConnection.ipAddresses; }); }; diff --git a/configurers/static.nix b/configurers/static.nix index 4057ee9..56d2557 100644 --- a/configurers/static.nix +++ b/configurers/static.nix @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -{lib, ...}@inputs: keyProviders: intermediateConfig: peerName: +{lib, ...}@inputs: keyProviders: intermediateConfig: localPeerName: with lib.trivial; with lib.attrsets; with lib.lists; @@ -11,28 +11,28 @@ with lib; with builtins; with import ../lib.nix; let - thisPeer = intermediateConfig.peers."${peerName}"; + thisPeer = intermediateConfig.peers."${localPeerName}"; # these aren't really important, I just wanted to reverse the argument order forEachAttr' = flip mapAttrs'; forEachAttrToList = flip mapAttrsToList; in -with getKeyProviderFuncs keyProviders inputs intermediateConfig peerName; +with getKeyProviderFuncs keyProviders inputs intermediateConfig localPeerName; { networking.extraHosts = concatStringsSep "\n" (concatLists ( concatLists (forEachAttrToList thisPeer.subnetConnections (subnetName: subnetConnection: - forEachAttrToList subnetConnection.peerConnections (otherPeerName: peerConnection: forEach peerConnection.ipAddresses (ip: "${strings.removeSuffix "/64" ip} ${otherPeerName}.${subnetName}")) + forEachAttrToList subnetConnection.peerConnections (remotePeerName: peerConnection: forEach peerConnection.ipAddresses (ip: "${strings.removeSuffix "/64" ip} ${remotePeerName}.${subnetName}")) )))); networking.wireguard = { - interfaces = forEachAttr' thisPeer.subnetConnections (subnetName: subnetConnection: nameValuePair "wn-${subnetName}" + interfaces = forEachAttr' thisPeer.subnetConnections (subnetName: subnetConnection: nameValuePair "${head (strings.splitString "." subnetName)}" { ips = subnetConnection.ipAddresses; listenPort = subnetConnection.listenPort; privateKeyFile = getPrivKeyFile; - peers = forEachAttrToList subnetConnection.peerConnections (otherPeerName: peerConnection: + peers = forEachAttrToList subnetConnection.peerConnections (remotePeerName: peerConnection: { - name = otherPeerName; - publicKey = getPeerPubKey otherPeerName; + name = remotePeerName; + publicKey = getPeerPubKey remotePeerName; presharedKeyFile = getSubnetPSKFile subnetName; - allowedIPs = peerConnection.ipAddresses; + allowedIPs = map (ip: cidr2ip ip + "/128") peerConnection.ipAddresses; endpoint = "${peerConnection.endpoint.ip}:${builtins.toString peerConnection.endpoint.port}"; } // (mergeIf peerConnection.endpoint "persistentKeepalive") diff --git a/key-providers/acl.nix b/key-providers/acl.nix index 4235850..6e16f38 100644 --- a/key-providers/acl.nix +++ b/key-providers/acl.nix @@ -3,12 +3,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -{lib, ...}: intermediateConfig: peerName: +{lib, ...}: intermediateConfig: localPeerName: with import ../lib.nix; with lib.attrsets; with builtins; { - getPeerPubKey = otherPeerName: attrByPath [otherPeerName "publicKey"] null intermediateConfig.peers; - getPrivKeyFile = attrByPath [peerName "privateKeyFile"] null intermediateConfig.peers; + getPeerPubKey = remotePeerName: attrByPath [remotePeerName "publicKey"] null intermediateConfig.peers; + getPrivKeyFile = attrByPath [localPeerName "privateKeyFile"] null intermediateConfig.peers; getSubnetPSKFile = subnetName: attrByPath [subnetName "presharedKeyFile"] null intermediateConfig.subnets; } \ No newline at end of file diff --git a/key-providers/agenix-rekey.nix b/key-providers/agenix-rekey.nix index 4f542ea..7acc383 100644 --- a/key-providers/agenix-rekey.nix +++ b/key-providers/agenix-rekey.nix @@ -3,15 +3,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -{config, lib, ...}: intermediateConfig: peerName: +{config, lib, ...}: intermediateConfig: localPeerName: with (import ../lib.nix); with lib.attrsets; with builtins; { config.age = { secrets = { - "wirenix-peer-${peerName}" = { - rekeyFile = config.wirenix.secretsDir + /wirenix-peer- + peerName + ".age"; + "wirenix-peer-${localPeerName}" = { + owner = "root"; + mode = "640"; + group = if config.wirenix.configurer == "networkd" then "systemd-network" else "root"; + rekeyFile = config.wirenix.secretsDir + /wirenix-peer- + localPeerName + ".age"; generator.script = {pkgs, file, ...}: '' priv=$(${pkgs.wireguard-tools}/bin/wg genkey) ${pkgs.wireguard-tools}/bin/wg pubkey <<< "$priv" > ${lib.escapeShellArg (lib.removeSuffix ".age" file + ".pub")} @@ -20,14 +23,17 @@ with builtins; }; } // mapAttrs' (name: value: nameValuePair ("wirenix-subnet-${name}") { + owner = "root"; + mode = "640"; + group = if config.wirenix.configurer == "networkd" then "systemd-network" else "root"; rekeyFile = config.wirenix.secretsDir + /wirenix-subnet- + name + ".age"; generator.script = {pkgs, ...}: '' psk=$(${pkgs.wireguard-tools}/bin/wg genpsk) echo "$psk" ''; - }) intermediateConfig.peers."${peerName}".subnetConnections; + }) intermediateConfig.peers."${localPeerName}".subnetConnections; }; - getPeerPubKey = otherPeerName: builtins.readFile (config.wirenix.secretsDir + /wirenix-peer-${peerName}.pub); - getPrivKeyFile = config.age.secrets."wirenix-peer-${peerName}".path; + getPeerPubKey = remotePeerName: builtins.readFile (config.wirenix.secretsDir + /wirenix-peer-${remotePeerName}.pub); + getPrivKeyFile = config.age.secrets."wirenix-peer-${localPeerName}".path; getSubnetPSKFile = subnetName: config.age.secrets."wirenix-subnet-${subnetName}".path; } \ No newline at end of file diff --git a/lib.nix b/lib.nix index adeed6a..46d238a 100644 --- a/lib.nix +++ b/lib.nix @@ -127,4 +127,5 @@ rec { }; mergeIf = attr: key: if builtins.hasAttr key attr then {"${key}" = attr."${key}";} else {}; + cidr2ip = cidr: head (filter (item: item != []) (split "/" cidr)); } \ No newline at end of file diff --git a/net.nix b/net.nix new file mode 100644 index 0000000..e69de29