diff --git a/nixos/modules/security/dhparams.nix b/nixos/modules/security/dhparams.nix
index 64b296eea5b..481d4c5db51 100644
--- a/nixos/modules/security/dhparams.nix
+++ b/nixos/modules/security/dhparams.nix
@@ -1,8 +1,7 @@
{ config, lib, pkgs, ... }:
-with lib;
-
let
+ inherit (lib) mkOption types;
cfg = config.security.dhparams;
paramsSubmodule = { name, config, ... }: {
@@ -39,32 +38,39 @@ let
in {
options = {
security.dhparams = {
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to generate new DH params and clean up old DH params.
+ '';
+ };
+
params = mkOption {
- description =
- ''
- Diffie-Hellman parameters to generate.
-
- The value is the size (in bits) of the DH params to generate. The
- generated DH params path can be found in
- config.security.dhparams.params.name.path.
-
- The name of the DH params is taken as being the name of
- the service it serves and the params will be generated before the
- said service is started.
-
- If you are removing all dhparams from this list, you
- have to leave for at
- least one activation in order to have them be cleaned up. This also
- means if you rollback to a version without any dhparams the
- existing ones won't be cleaned up. Of course this only applies if
- is
- true.
- '';
type = with types; let
coerce = bits: { inherit bits; };
- in attrsOf (coercedTo types.int coerce (submodule paramsSubmodule));
+ in attrsOf (coercedTo int coerce (submodule paramsSubmodule));
default = {};
- example = literalExample "{ nginx.bits = 3072; }";
+ example = lib.literalExample "{ nginx.bits = 3072; }";
+ description = ''
+ Diffie-Hellman parameters to generate.
+
+ The value is the size (in bits) of the DH params to generate. The
+ generated DH params path can be found in
+ config.security.dhparams.params.name.path.
+
+ The name of the DH params is taken as being the name of
+ the service it serves and the params will be generated before the
+ said service is started.
+
+ If you are removing all dhparams from this list, you
+ have to leave for at
+ least one activation in order to have them be cleaned up. This also
+ means if you rollback to a version without any dhparams the
+ existing ones won't be cleaned up. Of course this only applies if
+ is
+ true.
+ '';
};
stateful = mkOption {
@@ -84,77 +90,67 @@ in {
};
path = mkOption {
+ type = types.str;
+ default = "/var/lib/dhparams";
description = ''
Path to the directory in which Diffie-Hellman parameters will be
stored. This only is relevant if
is
true.
'';
- type = types.str;
- default = "/var/lib/dhparams";
- };
-
- enable = mkOption {
- description =
- ''
- Whether to generate new DH params and clean up old DH params.
- '';
- default = false;
- type = types.bool;
};
};
};
- config = mkIf (cfg.enable && cfg.stateful) {
+ config = lib.mkIf (cfg.enable && cfg.stateful) {
systemd.services = {
dhparams-init = {
- description = "Cleanup old Diffie-Hellman parameters";
- wantedBy = [ "multi-user.target" ]; # Clean up even when no DH params is set
- serviceConfig.Type = "oneshot";
- script =
- # Create directory
- ''
- if [ ! -d ${cfg.path} ]; then
- mkdir -p ${cfg.path}
- fi
- '' +
- # Remove old dhparams
- ''
- for file in ${cfg.path}/*; do
- if [ ! -f "$file" ]; then
- continue
- fi
- '' + concatStrings (mapAttrsToList (name: { bits, ... }:
- ''
- if [ "$file" == "${cfg.path}/${name}.pem" ] && \
- ${pkgs.openssl}/bin/openssl dhparam -in "$file" -text | head -n 1 | grep "(${toString bits} bit)" > /dev/null; then
- continue
- fi
- ''
- ) cfg.params) +
- ''
- rm $file
- done
+ description = "Clean Up Old Diffie-Hellman Parameters";
- # TODO: Ideally this would be removing the *former* cfg.path, though this
- # does not seem really important as changes to it are quite unlikely
- rmdir --ignore-fail-on-non-empty ${cfg.path}
- '';
- };
- } //
- mapAttrs' (name: { bits, ... }: nameValuePair "dhparams-gen-${name}" {
- description = "Generate Diffie-Hellman parameters for ${name} if they don't exist yet";
- after = [ "dhparams-init.service" ];
- before = [ "${name}.service" ];
+ # Clean up even when no DH params is set
wantedBy = [ "multi-user.target" ];
+
+ serviceConfig.RemainAfterExit = true;
serviceConfig.Type = "oneshot";
- script =
- ''
+
+ script = ''
+ if [ ! -d ${cfg.path} ]; then
mkdir -p ${cfg.path}
- if [ ! -f ${cfg.path}/${name}.pem ]; then
- ${pkgs.openssl}/bin/openssl dhparam -out ${cfg.path}/${name}.pem ${toString bits}
+ fi
+
+ # Remove old dhparams
+ for file in ${cfg.path}/*; do
+ if [ ! -f "$file" ]; then
+ continue
fi
- '';
- }) cfg.params;
+ ${lib.concatStrings (lib.mapAttrsToList (name: { bits, path, ... }: ''
+ if [ "$file" = ${lib.escapeShellArg path} ] && \
+ ${pkgs.openssl}/bin/openssl dhparam -in "$file" -text \
+ | head -n 1 | grep "(${toString bits} bit)" > /dev/null; then
+ continue
+ fi
+ '') cfg.params)}
+ rm $file
+ done
+
+ # TODO: Ideally this would be removing the *former* cfg.path, though
+ # this does not seem really important as changes to it are quite
+ # unlikely
+ rmdir --ignore-fail-on-non-empty ${cfg.path}
+ '';
+ };
+ } // lib.mapAttrs' (name: { bits, path, ... }: lib.nameValuePair "dhparams-gen-${name}" {
+ description = "Generate Diffie-Hellman Parameters for ${name}";
+ after = [ "dhparams-init.service" ];
+ before = [ "${name}.service" ];
+ wantedBy = [ "multi-user.target" ];
+ unitConfig.ConditionPathExists = "!${path}";
+ serviceConfig.Type = "oneshot";
+ script = ''
+ mkdir -p ${lib.escapeShellArg cfg.path}
+ ${pkgs.openssl}/bin/openssl dhparam -out ${lib.escapeShellArg path} \
+ ${toString bits}
+ '';
+ }) cfg.params;
};
}