nixpkgs/nixos/tests/dhparams.nix

131 lines
4.7 KiB
Nix
Raw Normal View History

2022-11-11 00:50:06 +00:00
import ./make-test-python.nix {
name = "dhparams";
2022-11-11 00:50:06 +00:00
nodes.machine = { pkgs, ... }: {
security.dhparams.enable = true;
environment.systemPackages = [ pkgs.openssl ];
2022-11-11 00:50:06 +00:00
specialisation = {
gen1.configuration = { config, ... }: {
security.dhparams.params = {
# Use low values here because we don't want the test to run for ages.
foo.bits = 1024;
# Also use the old format to make sure the type is coerced in the right
# way.
bar = 1025;
};
systemd.services.foo = {
description = "Check systemd Ordering";
wantedBy = [ "multi-user.target" ];
before = [ "shutdown.target" ];
conflicts = [ "shutdown.target" ];
2022-11-11 00:50:06 +00:00
unitConfig = {
# This is to make sure that the dhparams generation of foo occurs
# before this service so we need this service to start as early as
# possible to provoke a race condition.
DefaultDependencies = false;
# We check later whether the service has been started or not.
ConditionPathExists = config.security.dhparams.params.foo.path;
};
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
# The reason we only provide an ExecStop here is to ensure that we don't
# accidentally trigger an error because a file system is not yet ready
# during very early startup (we might not even have the Nix store
# available, for example if future changes in NixOS use systemd mount
# units to do early file system initialisation).
serviceConfig.ExecStop = "${pkgs.coreutils}/bin/true";
};
};
gen2.configuration = {
security.dhparams.params.foo.bits = 1026;
};
gen3.configuration = {};
gen4.configuration = {
security.dhparams.stateful = false;
security.dhparams.params.foo2.bits = 1027;
security.dhparams.params.bar2.bits = 1028;
};
gen5.configuration = {
security.dhparams.defaultBitSize = 1029;
security.dhparams.params.foo3 = {};
security.dhparams.params.bar3 = {};
};
};
};
testScript = { nodes, ... }: let
getParamPath = gen: name: let
2022-11-11 00:50:06 +00:00
node = "gen${toString gen}";
in nodes.machine.config.specialisation.${node}.configuration.security.dhparams.params.${name}.path;
switchToGeneration = gen: let
2022-11-11 00:50:06 +00:00
switchCmd = "${nodes.machine.config.system.build.toplevel}/specialisation/gen${toString gen}/bin/switch-to-configuration test";
in ''
2019-12-06 06:05:06 +00:00
with machine.nested("switch to generation ${toString gen}"):
2022-11-11 00:50:06 +00:00
machine.succeed("${switchCmd}")
'';
in ''
2019-12-06 06:05:06 +00:00
import re
2019-12-06 06:05:06 +00:00
def assert_param_bits(path, bits):
with machine.nested(f"check bit size of {path}"):
output = machine.succeed(f"openssl dhparam -in {path} -text")
pattern = re.compile(r"^\s*DH Parameters:\s+\((\d+)\s+bit\)\s*$", re.M)
match = pattern.match(output)
if match is None:
raise Exception("bla")
if match[1] != str(bits):
raise Exception(f"bit size should be {bits} but it is {match[1]} instead.")
2019-12-06 06:05:06 +00:00
machine.wait_for_unit("multi-user.target")
2022-11-11 00:50:06 +00:00
${switchToGeneration 1}
2019-12-06 06:05:06 +00:00
with subtest("verify startup order"):
machine.succeed("systemctl is-active foo.service")
with subtest("check bit sizes of dhparam files"):
2022-11-11 00:50:06 +00:00
assert_param_bits("${getParamPath 1 "foo"}", 1024)
assert_param_bits("${getParamPath 1 "bar"}", 1025)
${switchToGeneration 2}
2019-12-06 06:05:06 +00:00
with subtest("check whether bit size has changed"):
2022-11-11 00:50:06 +00:00
assert_param_bits("${getParamPath 2 "foo"}", 1026)
2019-12-06 06:05:06 +00:00
with subtest("ensure that dhparams file for 'bar' was deleted"):
machine.fail("test -e ${getParamPath 1 "bar"}")
${switchToGeneration 3}
2019-12-06 06:05:06 +00:00
with subtest("ensure that 'security.dhparams.path' has been deleted"):
2022-11-11 00:50:06 +00:00
machine.fail("test -e ${nodes.machine.config.specialisation.gen3.configuration.security.dhparams.path}")
nixos/dhparams: Introduce a 'stateful' option This option allows us to turn off stateful generation of Diffie-Hellman parameters, which in some way is still stateful as the generated DH params file is non-deterministic. However what we can avoid with this is to have an increased surface for failures during system startup, because generation of the parameters is done during build-time. Another advantage of this is that we no longer need to take care of cleaning up the files that are no longer used and in my humble opinion I would have preferred that #11505 (which puts the dhparams in the Nix store) would have been merged instead of #22634 (which we have now). Luckily we can still change that and this change gives the user the option to put the dhparams into the Nix store. Beside of the more obvious advantages pointed out here, this also effects test runtime if more services are starting to use this (for example see #39507 and #39288), because generating DH params could take a long time depending on the bit size which adds up to test runtime. If we generate the DH params in a separate derivation, subsequent test runs won't need to wait for DH params generation during bootup. Of course, tests could still mock this by force-disabling the service and adding a service or activation script that places pre-generated DH params in /var/lib/dhparams but this would make tests less readable and the workaround would have to be made for each test affected. Note that the 'stateful' option is still true by default so that we are backwards-compatible with existing systems. Signed-off-by: aszlig <aszlig@nix.build> Cc: @Ekleog, @abbradar, @fpletz
2018-04-26 04:38:02 +00:00
${switchToGeneration 4}
2019-12-06 06:05:06 +00:00
with subtest("check bit sizes dhparam files"):
assert_param_bits(
2022-11-11 00:50:06 +00:00
"${getParamPath 4 "foo2"}", 1027
2019-12-06 06:05:06 +00:00
)
assert_param_bits(
2022-11-11 00:50:06 +00:00
"${getParamPath 4 "bar2"}", 1028
2019-12-06 06:05:06 +00:00
)
nixos/dhparams: Introduce a 'stateful' option This option allows us to turn off stateful generation of Diffie-Hellman parameters, which in some way is still stateful as the generated DH params file is non-deterministic. However what we can avoid with this is to have an increased surface for failures during system startup, because generation of the parameters is done during build-time. Another advantage of this is that we no longer need to take care of cleaning up the files that are no longer used and in my humble opinion I would have preferred that #11505 (which puts the dhparams in the Nix store) would have been merged instead of #22634 (which we have now). Luckily we can still change that and this change gives the user the option to put the dhparams into the Nix store. Beside of the more obvious advantages pointed out here, this also effects test runtime if more services are starting to use this (for example see #39507 and #39288), because generating DH params could take a long time depending on the bit size which adds up to test runtime. If we generate the DH params in a separate derivation, subsequent test runs won't need to wait for DH params generation during bootup. Of course, tests could still mock this by force-disabling the service and adding a service or activation script that places pre-generated DH params in /var/lib/dhparams but this would make tests less readable and the workaround would have to be made for each test affected. Note that the 'stateful' option is still true by default so that we are backwards-compatible with existing systems. Signed-off-by: aszlig <aszlig@nix.build> Cc: @Ekleog, @abbradar, @fpletz
2018-04-26 04:38:02 +00:00
2019-12-06 06:05:06 +00:00
with subtest("check whether dhparam files are in the Nix store"):
machine.succeed(
"expr match ${getParamPath 4 "foo2"} ${builtins.storeDir}",
"expr match ${getParamPath 4 "bar2"} ${builtins.storeDir}",
)
${switchToGeneration 5}
2019-12-06 06:05:06 +00:00
with subtest("check whether defaultBitSize works as intended"):
2022-11-11 00:50:06 +00:00
assert_param_bits("${getParamPath 5 "foo3"}", 1029)
assert_param_bits("${getParamPath 5 "bar3"}", 1029)
'';
}