nixos/networkd: support systemd-creds in WireGuard (#346964)

This commit is contained in:
Will Fancher 2024-10-15 14:31:27 -04:00 committed by GitHub
commit a6e54f566a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 8 deletions

View File

@ -17,6 +17,7 @@ let
filterAttrs
flatten
flip
hasPrefix
head
isInt
isFloat
@ -196,6 +197,10 @@ in rec {
optional (attr ? ${name})
"Systemd ${group} field `${name}' has been removed. See ${see}";
assertKeyIsSystemdCredential = name: group: attr:
optional (attr ? ${name} && !(hasPrefix "@" attr.${name}))
"Systemd ${group} field `${name}' is not a systemd credential";
checkUnitConfig = group: checks: attrs: let
# We're applied at the top-level type (attrsOf unitOption), so the actual
# unit options might contain attributes from mkOverride and mkIf that we need to

View File

@ -411,11 +411,14 @@ let
(assertValueOneOf "Layer2SpecificHeader" [ "none" "default" ])
];
# NOTE The PrivateKey directive is missing on purpose here, please
# do not add it to this list. The nix store is world-readable let's
# refrain ourselves from providing a footgun.
# NOTE Check whether the key starts with an @, in which case it is
# interpreted as the name of the credential from which the actual key
# shall be read by systemd-creds.
# Do not remove this check as the nix store is world-readable.
sectionWireGuard = checkUnitConfig "WireGuard" [
(assertKeyIsSystemdCredential "PrivateKey")
(assertOnlyFields [
"PrivateKey"
"PrivateKeyFile"
"ListenPort"
"FirewallMark"
@ -426,12 +429,15 @@ let
(assertRange "FirewallMark" 1 4294967295)
];
# NOTE The PresharedKey directive is missing on purpose here, please
# do not add it to this list. The nix store is world-readable,let's
# refrain ourselves from providing a footgun.
# NOTE Check whether the key starts with an @, in which case it is
# interpreted as the name of the credential from which the actual key
# shall be read by systemd-creds.
# Do not remove this check as the nix store is world-readable.
sectionWireGuardPeer = checkUnitConfigWithLegacyKey "wireguardPeerConfig" "WireGuardPeer" [
(assertKeyIsSystemdCredential "PresharedKey")
(assertOnlyFields [
"PublicKey"
"PresharedKey"
"PresharedKeyFile"
"AllowedIPs"
"Endpoint"

View File

@ -1,4 +1,4 @@
let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
let generateNodeConf = { lib, pkgs, config, privk, pubk, systemdCreds, peerId, nodeId, ...}: {
imports = [ common/user-account.nix ];
systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
networking.useNetworkd = true;
@ -6,6 +6,7 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
networking.firewall.enable = false;
virtualisation.vlans = [ 1 ];
environment.systemPackages = with pkgs; [ wireguard-tools ];
environment.etc."credstore/network.wireguard.private" = lib.mkIf systemdCreds { text = privk; };
systemd.network = {
enable = true;
config = {
@ -15,11 +16,14 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
"90-wg0" = {
netdevConfig = { Kind = "wireguard"; Name = "wg0"; };
wireguardConfig = {
# Test storing wireguard private key using systemd credentials.
PrivateKey = lib.mkIf systemdCreds "@network.wireguard.private";
# NOTE: we're storing the wireguard private key in the
# store for this test. Do not do this in the real
# world. Keep in mind the nix store is
# world-readable.
PrivateKeyFile = pkgs.writeText "wg0-priv" privk;
PrivateKeyFile = lib.mkIf (!systemdCreds) (pkgs.writeText "wg0-priv" privk);
ListenPort = 51820;
FirewallMark = 42;
};
@ -74,6 +78,7 @@ in import ./make-test-python.nix ({pkgs, ... }: {
let localConf = {
privk = "GDiXWlMQKb379XthwX0haAbK6hTdjblllpjGX0heP00=";
pubk = "iRxpqj42nnY0Qz8MAQbSm7bXxXP5hkPqWYIULmvW+EE=";
systemdCreds = false;
nodeId = "1";
peerId = "2";
};
@ -83,6 +88,7 @@ in import ./make-test-python.nix ({pkgs, ... }: {
let localConf = {
privk = "eHxSI2jwX/P4AOI0r8YppPw0+4NZnjOxfbS5mt06K2k=";
pubk = "27s0OvaBBdHoJYkH9osZpjpgSOVNw+RaKfboT/Sfq0g=";
systemdCreds = true;
nodeId = "2";
peerId = "1";
};