wireguard: allow not storing private keys in world-readable /nix/store (#27433)

* wireguard: allow not storing private keys in world-readable /nix/store
wip/yesman
Aristid Breitkreuz 7 years ago committed by GitHub
parent 7ba1c7a9fb
commit 9b0ff955fd
  1. 85
      nixos/modules/services/networking/wireguard.nix

@ -23,8 +23,23 @@ let
privateKey = mkOption {
example = "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=";
type = types.str;
description = "Base64 private key generated by wg genkey.";
type = with types; nullOr str;
default = null;
description = ''
Base64 private key generated by wg genkey.
Warning: Consider using privateKeyFile instead if you do not
want to store the key in the world-readable Nix store.
'';
};
privateKeyFile = mkOption {
example = "/private/wireguard_key";
type = with types; nullOr str;
default = null;
description = ''
Private key file as generated by wg genkey.
'';
};
listenPort = mkOption {
@ -91,7 +106,22 @@ let
example = "rVXs/Ni9tu3oDBLS4hOyAUAa1qTWVA3loR8eL20os3I=";
type = with types; nullOr str;
description = ''
base64 preshared key generated by wg genpsk. Optional,
Base64 preshared key generated by wg genpsk. Optional,
and may be omitted. This option adds an additional layer of
symmetric-key cryptography to be mixed into the already existing
public-key cryptography, for post-quantum resistance.
Warning: Consider using presharedKeyFile instead if you do not
want to store the key in the world-readable Nix store.
'';
};
presharedKeyFile = mkOption {
default = null;
example = "/private/wireguard_psk";
type = with types; nullOr str;
description = ''
File pointing to preshared key as generated by wg pensk. Optional,
and may be omitted. This option adds an additional layer of
symmetric-key cryptography to be mixed into the already existing
public-key cryptography, for post-quantum resistance.
@ -134,54 +164,59 @@ let
};
generateConf = name: values: pkgs.writeText "wireguard-${name}.conf" ''
[Interface]
PrivateKey = ${values.privateKey}
${optionalString (values.listenPort != null) "ListenPort = ${toString values.listenPort}"}
${concatStringsSep "\n\n" (map (peer: ''
[Peer]
PublicKey = ${peer.publicKey}
${optionalString (peer.presharedKey != null) "PresharedKey = ${peer.presharedKey}"}
${optionalString (peer.allowedIPs != []) "AllowedIPs = ${concatStringsSep ", " peer.allowedIPs}"}
${optionalString (peer.endpoint != null) "Endpoint = ${peer.endpoint}"}
${optionalString (peer.persistentKeepalive != null) "PersistentKeepalive = ${toString peer.persistentKeepalive}"}
'') values.peers)}
'';
ipCommand = "${pkgs.iproute}/bin/ip";
wgCommand = "${pkgs.wireguard}/bin/wg";
generateUnit = name: values:
# exactly one way to specify the private key must be set
assert (values.privateKey != null) != (values.privateKeyFile != null);
let privKey = if values.privateKeyFile != null then values.privateKeyFile else pkgs.writeText "wg-key" values.privateKey;
in
nameValuePair "wireguard-${name}"
{
description = "WireGuard Tunnel - ${name}";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = lib.flatten([
ExecStart = flatten([
values.preSetup
"-${ipCommand} link del dev ${name}"
"${ipCommand} link add dev ${name} type wireguard"
"${wgCommand} setconf ${name} ${generateConf name values}"
(map (ip:
''${ipCommand} address add ${ip} dev ${name}''
"${ipCommand} address add ${ip} dev ${name}"
) values.ips)
("${wgCommand} set ${name} private-key ${privKey}" +
optionalString (values.listenPort != null) " listen-port ${toString values.listenPort}")
(map (peer:
assert (peer.presharedKeyFile == null) || (peer.presharedKey == null); # at most one of the two must be set
let psk = if peer.presharedKey != null then pkgs.writeText "wg-psk" peer.presharedKey else peer.presharedKeyFile;
in
"${wgCommand} set ${name} peer ${peer.publicKey}" +
optionalString (psk != null) " preshared-key ${psk}" +
optionalString (peer.endpoint != null) " endpoint ${peer.endpoint}" +
optionalString (peer.persistentKeepalive != null) " persistent-keepalive ${toString peer.persistentKeepalive}" +
optionalString (peer.allowedIPs != []) " allowed-ips ${concatStringsSep "," peer.allowedIPs}"
) values.peers)
"${ipCommand} link set up dev ${name}"
(flatten (map (peer: (map (ip:
(map (peer: (map (ip:
"${ipCommand} route add ${ip} dev ${name}"
) peer.allowedIPs)) values.peers))
) peer.allowedIPs)) values.peers)
values.postSetup
]);
ExecStop = [ ''${ipCommand} link del dev "${name}"'' ] ++ values.postShutdown;
ExecStop = flatten([
"${ipCommand} link del dev ${name}"
values.postShutdown
]);
};
};

Loading…
Cancel
Save