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

* wireguard: allow not storing private keys in world-readable /nix/store
This commit is contained in:
Aristid Breitkreuz 2017-07-17 23:55:31 +02:00 committed by GitHub
parent 7ba1c7a9fb
commit 9b0ff955fd

View File

@ -23,8 +23,23 @@ let
privateKey = mkOption { privateKey = mkOption {
example = "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk="; example = "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=";
type = types.str; type = with types; nullOr str;
description = "Base64 private key generated by wg genkey."; 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 { listenPort = mkOption {
@ -91,7 +106,22 @@ let
example = "rVXs/Ni9tu3oDBLS4hOyAUAa1qTWVA3loR8eL20os3I="; example = "rVXs/Ni9tu3oDBLS4hOyAUAa1qTWVA3loR8eL20os3I=";
type = with types; nullOr str; type = with types; nullOr str;
description = '' 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 and may be omitted. This option adds an additional layer of
symmetric-key cryptography to be mixed into the already existing symmetric-key cryptography to be mixed into the already existing
public-key cryptography, for post-quantum resistance. 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"; ipCommand = "${pkgs.iproute}/bin/ip";
wgCommand = "${pkgs.wireguard}/bin/wg"; wgCommand = "${pkgs.wireguard}/bin/wg";
generateUnit = name: values: 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}" nameValuePair "wireguard-${name}"
{ {
description = "WireGuard Tunnel - ${name}"; description = "WireGuard Tunnel - ${name}";
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true; RemainAfterExit = true;
ExecStart = lib.flatten([ ExecStart = flatten([
values.preSetup values.preSetup
"-${ipCommand} link del dev ${name}" "-${ipCommand} link del dev ${name}"
"${ipCommand} link add dev ${name} type wireguard" "${ipCommand} link add dev ${name} type wireguard"
"${wgCommand} setconf ${name} ${generateConf name values}"
(map (ip: (map (ip:
''${ipCommand} address add ${ip} dev ${name}'' "${ipCommand} address add ${ip} dev ${name}"
) values.ips) ) 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}" "${ipCommand} link set up dev ${name}"
(flatten (map (peer: (map (ip: (map (peer: (map (ip:
"${ipCommand} route add ${ip} dev ${name}" "${ipCommand} route add ${ip} dev ${name}"
) peer.allowedIPs)) values.peers)) ) peer.allowedIPs)) values.peers)
values.postSetup values.postSetup
]); ]);
ExecStop = flatten([
ExecStop = [ ''${ipCommand} link del dev "${name}"'' ] ++ values.postShutdown; "${ipCommand} link del dev ${name}"
values.postShutdown
]);
}; };
}; };