Skip to content

Commit

Permalink
wireguard: allow not storing private keys in world-readable /nix/store (
Browse files Browse the repository at this point in the history
#27433)

* wireguard: allow not storing private keys in world-readable /nix/store
  • Loading branch information
aristidb committed Jul 17, 2017
1 parent 7ba1c7a commit 9b0ff95
Showing 1 changed file with 60 additions and 25 deletions.
85 changes: 60 additions & 25 deletions nixos/modules/services/networking/wireguard.nix
Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
]);
};
};

Expand Down

0 comments on commit 9b0ff95

Please sign in to comment.