nixos/dhparams: Turn params into a submodule
We're going to implement an option which allows us to turn off stateful handling of Diffie-Hellman parameter files by putting them into the Nix store. However, modules now might need a way to reference these files, so we add a now path option to every param specified, which carries a read-only value of the path where to find the corresponding DH params file. I've also improved the description of security.dhparams.params a bit so that it uses <warning/> and <note/>. The NixOS VM test also reflects this change and checks whether the old way to specify the bit size still works. Signed-off-by: aszlig <aszlig@nix.build> Cc: @Ekleog
This commit is contained in:
parent
4de774a63b
commit
761266bd18
@ -1,10 +1,38 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.security.dhparams;
|
cfg = config.security.dhparams;
|
||||||
in
|
|
||||||
{
|
paramsSubmodule = { name, config, ... }: {
|
||||||
|
options.bits = mkOption {
|
||||||
|
type = types.addCheck types.int (b: b >= 16) // {
|
||||||
|
name = "bits";
|
||||||
|
description = "integer of at least 16 bits";
|
||||||
|
};
|
||||||
|
default = 4096;
|
||||||
|
description = ''
|
||||||
|
The bit size for the prime that is used during a Diffie-Hellman
|
||||||
|
key exchange.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
options.path = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
readOnly = true;
|
||||||
|
description = ''
|
||||||
|
The resulting path of the generated Diffie-Hellman parameters
|
||||||
|
file for other services to reference. This could be either a
|
||||||
|
store path or a file inside the directory specified by
|
||||||
|
<option>security.dhparams.path</option>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
config.path = "${cfg.path}/${name}.pem";
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
options = {
|
options = {
|
||||||
security.dhparams = {
|
security.dhparams = {
|
||||||
params = mkOption {
|
params = mkOption {
|
||||||
@ -14,21 +42,23 @@ in
|
|||||||
|
|
||||||
The value is the size (in bits) of the DH params to generate. The
|
The value is the size (in bits) of the DH params to generate. The
|
||||||
generated DH params path can be found in
|
generated DH params path can be found in
|
||||||
<filename><replaceable>security.dhparams.path</replaceable>/<replaceable>name</replaceable>.pem</filename>.
|
<literal>config.security.dhparams.params.<replaceable>name</replaceable>.path</literal>.
|
||||||
|
|
||||||
Note: The name of the DH params is taken as being the name of the
|
<note><para>The name of the DH params is taken as being the name of
|
||||||
service it serves: the params will be generated before the said
|
the service it serves and the params will be generated before the
|
||||||
service is started.
|
said service is started.</para></note>
|
||||||
|
|
||||||
Warning: If you are removing all dhparams from this list, you have
|
<warning><para>If you are removing all dhparams from this list, you
|
||||||
to leave security.dhparams.enable for at least one activation in
|
have to leave <option>security.dhparams.enable</option> for at
|
||||||
order to have them be cleaned up. This also means if you rollback to
|
least one activation in order to have them be cleaned up. This also
|
||||||
a version without any dhparams the existing ones won't be cleaned
|
means if you rollback to a version without any dhparams the
|
||||||
up.
|
existing ones won't be cleaned up.</para></warning>
|
||||||
'';
|
'';
|
||||||
type = with types; attrsOf int;
|
type = with types; let
|
||||||
|
coerce = bits: { inherit bits; };
|
||||||
|
in attrsOf (coercedTo types.int coerce (submodule paramsSubmodule));
|
||||||
default = {};
|
default = {};
|
||||||
example = { nginx = 3072; };
|
example = literalExample "{ nginx.bits = 3072; }";
|
||||||
};
|
};
|
||||||
|
|
||||||
path = mkOption {
|
path = mkOption {
|
||||||
@ -71,10 +101,10 @@ in
|
|||||||
if [ ! -f "$file" ]; then
|
if [ ! -f "$file" ]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
'' + concatStrings (mapAttrsToList (name: value:
|
'' + concatStrings (mapAttrsToList (name: { bits, ... }:
|
||||||
''
|
''
|
||||||
if [ "$file" == "${cfg.path}/${name}.pem" ] && \
|
if [ "$file" == "${cfg.path}/${name}.pem" ] && \
|
||||||
${pkgs.openssl}/bin/openssl dhparam -in "$file" -text | head -n 1 | grep "(${toString value} bit)" > /dev/null; then
|
${pkgs.openssl}/bin/openssl dhparam -in "$file" -text | head -n 1 | grep "(${toString bits} bit)" > /dev/null; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
''
|
''
|
||||||
@ -89,7 +119,7 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
} //
|
} //
|
||||||
mapAttrs' (name: value: nameValuePair "dhparams-gen-${name}" {
|
mapAttrs' (name: { bits, ... }: nameValuePair "dhparams-gen-${name}" {
|
||||||
description = "Generate Diffie-Hellman parameters for ${name} if they don't exist yet";
|
description = "Generate Diffie-Hellman parameters for ${name} if they don't exist yet";
|
||||||
after = [ "dhparams-init.service" ];
|
after = [ "dhparams-init.service" ];
|
||||||
before = [ "${name}.service" ];
|
before = [ "${name}.service" ];
|
||||||
@ -99,7 +129,7 @@ in
|
|||||||
''
|
''
|
||||||
mkdir -p ${cfg.path}
|
mkdir -p ${cfg.path}
|
||||||
if [ ! -f ${cfg.path}/${name}.pem ]; then
|
if [ ! -f ${cfg.path}/${name}.pem ]; then
|
||||||
${pkgs.openssl}/bin/openssl dhparam -out ${cfg.path}/${name}.pem ${toString value}
|
${pkgs.openssl}/bin/openssl dhparam -out ${cfg.path}/${name}.pem ${toString bits}
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
}) cfg.params;
|
}) cfg.params;
|
||||||
|
@ -9,8 +9,13 @@ in import ./make-test.nix {
|
|||||||
|
|
||||||
nodes.generation1 = { pkgs, config, ... }: {
|
nodes.generation1 = { pkgs, config, ... }: {
|
||||||
imports = [ common ];
|
imports = [ common ];
|
||||||
security.dhparams.params.foo = 16;
|
security.dhparams.params = {
|
||||||
security.dhparams.params.bar = 17;
|
# Use low values here because we don't want the test to run for ages.
|
||||||
|
foo.bits = 16;
|
||||||
|
# Also use the old format to make sure the type is coerced in the right
|
||||||
|
# way.
|
||||||
|
bar = 17;
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.foo = {
|
systemd.services.foo = {
|
||||||
description = "Check systemd Ordering";
|
description = "Check systemd Ordering";
|
||||||
@ -22,7 +27,7 @@ in import ./make-test.nix {
|
|||||||
DefaultDependencies = false;
|
DefaultDependencies = false;
|
||||||
|
|
||||||
# We check later whether the service has been started or not.
|
# We check later whether the service has been started or not.
|
||||||
ConditionPathExists = "${config.security.dhparams.path}/foo.pem";
|
ConditionPathExists = config.security.dhparams.params.foo.path;
|
||||||
};
|
};
|
||||||
serviceConfig.Type = "oneshot";
|
serviceConfig.Type = "oneshot";
|
||||||
serviceConfig.RemainAfterExit = true;
|
serviceConfig.RemainAfterExit = true;
|
||||||
@ -37,7 +42,7 @@ in import ./make-test.nix {
|
|||||||
|
|
||||||
nodes.generation2 = {
|
nodes.generation2 = {
|
||||||
imports = [ common ];
|
imports = [ common ];
|
||||||
security.dhparams.params.foo = 18;
|
security.dhparams.params.foo.bits = 18;
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes.generation3 = common;
|
nodes.generation3 = common;
|
||||||
@ -45,8 +50,7 @@ in import ./make-test.nix {
|
|||||||
testScript = { nodes, ... }: let
|
testScript = { nodes, ... }: let
|
||||||
getParamPath = gen: name: let
|
getParamPath = gen: name: let
|
||||||
node = "generation${toString gen}";
|
node = "generation${toString gen}";
|
||||||
inherit (nodes.${node}.config.security.dhparams) path;
|
in nodes.${node}.config.security.dhparams.params.${name}.path;
|
||||||
in "${path}/${name}.pem";
|
|
||||||
|
|
||||||
assertParamBits = gen: name: bits: let
|
assertParamBits = gen: name: bits: let
|
||||||
path = getParamPath gen name;
|
path = getParamPath gen name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user