Unverified Commit 57d30c7a authored by Felix Uhl's avatar Felix Uhl Committed by GitHub
Browse files

nixos/wg-quick: add generatePrivateKeyFile option (#331253)

This option is already present in the wireguard module, but missing from
the wg-quick module. This is very annoying, because it means you can't
easily get a safe and valid configuration on first boot when using
wg-quick.

This change adds the same option with the same description text and the
same script, but instead of generating an entire systemd unit dedicated
to creating the key file, it adds the script as a PreUp script, which
is a much simpler solution.

I've tested this in my own configuration, and it does indeed work.
wg-quick allows multiple PreUp scripts, which are run in order, and
all PreUp scripts are run before the private key is read from disk,
see `man wg-quick`.
parent 12955826
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -57,6 +57,15 @@ let
        '';
      };

      generatePrivateKeyFile = mkOption {
        default = false;
        type = types.bool;
        description = ''
          Automatically generate a private key with
          {command}`wg genkey`, at the privateKeyFile location.
        '';
      };

      privateKeyFile = mkOption {
        example = "/private/wireguard_key";
        type = with types; nullOr str;
@@ -218,9 +227,24 @@ let

  writeScriptFile = name: text: ((pkgs.writeShellScriptBin name text) + "/bin/${name}");

  generatePrivateKeyScript = privateKeyFile: ''
    set -e

    # If the parent dir does not already exist, create it.
    # Otherwise, does nothing, keeping existing permissions intact.
    mkdir -p --mode 0755 "${dirOf privateKeyFile}"

    if [ ! -f "${privateKeyFile}" ]; then
      # Write private key file with atomically-correct permissions.
      (set -e; umask 077; wg genkey > "${privateKeyFile}")
    fi
  '';

  generateUnit = name: values:
    assert assertMsg (values.configFile != null || ((values.privateKey != null) != (values.privateKeyFile != null))) "Only one of privateKey, configFile or privateKeyFile may be set";
    assert assertMsg (values.generatePrivateKeyFile == false || values.privateKeyFile != null) "generatePrivateKeyFile requires privateKeyFile to be set";
    let
      generateKeyScriptFile = if values.generatePrivateKeyFile then writeScriptFile "generatePrivateKey.sh" (generatePrivateKeyScript values.privateKeyFile) else null;
      preUpFile = if values.preUp != "" then writeScriptFile "preUp.sh" values.preUp else null;
      postUp =
            optional (values.privateKeyFile != null) "wg set ${name} private-key <(cat ${values.privateKeyFile})" ++
@@ -247,6 +271,7 @@ let
        optionalString (values.mtu != null) "MTU = ${toString values.mtu}\n" +
        optionalString (values.privateKey != null) "PrivateKey = ${values.privateKey}\n" +
        optionalString (values.listenPort != null) "ListenPort = ${toString values.listenPort}\n" +
        optionalString (generateKeyScriptFile != null) "PreUp = ${generateKeyScriptFile}\n" +
        optionalString (preUpFile != null) "PreUp = ${preUpFile}\n" +
        optionalString (postUpFile != null) "PostUp = ${postUpFile}\n" +
        optionalString (preDownFile != null) "PreDown = ${preDownFile}\n" +