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
  • Loading branch information
aristidb committed Jul 16, 2017
1 parent b618843 commit c3cb467
Showing 1 changed file with 64 additions and 27 deletions.
91 changes: 64 additions & 27 deletions nixos/modules/services/networking/wireguard.nix
Expand Up @@ -23,8 +23,22 @@ 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 = ''
DEPRECATED BECAUSE IT PUTS A WORLD-READABLE COPY OF THE KEY IN /nix/store!
Base64 private key generated by wg genkey.
'';
};

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 +105,21 @@ let
example = "rVXs/Ni9tu3oDBLS4hOyAUAa1qTWVA3loR8eL20os3I=";
type = with types; nullOr str;
description = ''
base64 preshared key generated by wg genpsk. Optional,
DEPRECATED BECAUSE IT PUTS A WORLD-READABLE COPY OF THE KEY IN /nix/store!
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.
'';
};

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,15 +162,16 @@ let

};

generateConf = name: values: pkgs.writeText "wireguard-${name}.conf" ''
generateConf = name: values: ''
[Interface]
PrivateKey = ${values.privateKey}
PrivateKey = ${if values.privateKeyFile != null then "$(cat ${values.privateKeyFile})" else 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.presharedKeyFile != null) "PresharedKey = $(cat ${peer.presharedKeyFile})"}
${optionalString (peer.presharedKey != null && peer.presharedKeyFile == 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}"}
Expand All @@ -153,35 +182,43 @@ let
wgCommand = "${pkgs.wireguard}/bin/wg";

generateUnit = name: values:
assert (values.privateKey != null || values.privateKeyFile != null);
nameValuePair "wireguard-${name}"
{
description = "WireGuard Tunnel - ${name}";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
script = builtins.concatStringsSep "\n" (lib.flatten([
values.preSetup

''
${ipCommand} link del dev "${name}" || true
${ipCommand} link add dev ${name} type wireguard
${wgCommand} setconf ${name} /dev/stdin <<EOF
${generateConf name values}
EOF
''

(map (ip:
''${ipCommand} address add ${ip} dev ${name}''
) values.ips)

"${ipCommand} link set up dev ${name}"

(flatten (map (peer: (map (ip:
"${ipCommand} route add ${ip} dev ${name}"
) peer.allowedIPs)) values.peers))

values.postSetup
]));
preStop = builtins.concatStringsSep "\n" (lib.flatten([
''${ipCommand} link del dev "${name}"''
values.postShutdown
]));

serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = lib.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}''
) values.ips)

"${ipCommand} link set up dev ${name}"

(flatten (map (peer: (map (ip:
"${ipCommand} route add ${ip} dev ${name}"
) peer.allowedIPs)) values.peers))

values.postSetup
]);

ExecStop = [ ''${ipCommand} link del dev "${name}"'' ] ++ values.postShutdown;
};
};

Expand Down

0 comments on commit c3cb467

Please sign in to comment.