at 25.11-pre 5.2 kB view raw
1import ./make-test-python.nix { 2 name = "dhparams"; 3 4 nodes.machine = 5 { pkgs, ... }: 6 { 7 security.dhparams.enable = true; 8 environment.systemPackages = [ pkgs.openssl ]; 9 10 specialisation = { 11 gen1.configuration = 12 { config, ... }: 13 { 14 security.dhparams.params = { 15 # Use low values here because we don't want the test to run for ages. 16 foo.bits = 1024; 17 # Also use the old format to make sure the type is coerced in the right 18 # way. 19 bar = 1025; 20 }; 21 22 systemd.services.foo = { 23 description = "Check systemd Ordering"; 24 wantedBy = [ "multi-user.target" ]; 25 before = [ "shutdown.target" ]; 26 conflicts = [ "shutdown.target" ]; 27 unitConfig = { 28 # This is to make sure that the dhparams generation of foo occurs 29 # before this service so we need this service to start as early as 30 # possible to provoke a race condition. 31 DefaultDependencies = false; 32 33 # We check later whether the service has been started or not. 34 ConditionPathExists = config.security.dhparams.params.foo.path; 35 }; 36 serviceConfig.Type = "oneshot"; 37 serviceConfig.RemainAfterExit = true; 38 # The reason we only provide an ExecStop here is to ensure that we don't 39 # accidentally trigger an error because a file system is not yet ready 40 # during very early startup (we might not even have the Nix store 41 # available, for example if future changes in NixOS use systemd mount 42 # units to do early file system initialisation). 43 serviceConfig.ExecStop = "${pkgs.coreutils}/bin/true"; 44 }; 45 }; 46 gen2.configuration = { 47 security.dhparams.params.foo.bits = 1026; 48 }; 49 gen3.configuration = { }; 50 gen4.configuration = { 51 security.dhparams.stateful = false; 52 security.dhparams.params.foo2.bits = 1027; 53 security.dhparams.params.bar2.bits = 1028; 54 }; 55 gen5.configuration = { 56 security.dhparams.defaultBitSize = 1029; 57 security.dhparams.params.foo3 = { }; 58 security.dhparams.params.bar3 = { }; 59 }; 60 }; 61 }; 62 63 testScript = 64 { nodes, ... }: 65 let 66 getParamPath = 67 gen: name: 68 let 69 node = "gen${toString gen}"; 70 in 71 nodes.machine.config.specialisation.${node}.configuration.security.dhparams.params.${name}.path; 72 73 switchToGeneration = 74 gen: 75 let 76 switchCmd = "${nodes.machine.config.system.build.toplevel}/specialisation/gen${toString gen}/bin/switch-to-configuration test"; 77 in 78 '' 79 with machine.nested("switch to generation ${toString gen}"): 80 machine.succeed("${switchCmd}") 81 ''; 82 83 in 84 '' 85 import re 86 87 88 def assert_param_bits(path, bits): 89 with machine.nested(f"check bit size of {path}"): 90 output = machine.succeed(f"openssl dhparam -in {path} -text") 91 pattern = re.compile(r"^\s*DH Parameters:\s+\((\d+)\s+bit\)\s*$", re.M) 92 match = pattern.match(output) 93 if match is None: 94 raise Exception("bla") 95 if match[1] != str(bits): 96 raise Exception(f"bit size should be {bits} but it is {match[1]} instead.") 97 98 machine.wait_for_unit("multi-user.target") 99 ${switchToGeneration 1} 100 101 with subtest("verify startup order"): 102 machine.succeed("systemctl is-active foo.service") 103 104 with subtest("check bit sizes of dhparam files"): 105 assert_param_bits("${getParamPath 1 "foo"}", 1024) 106 assert_param_bits("${getParamPath 1 "bar"}", 1025) 107 108 ${switchToGeneration 2} 109 110 with subtest("check whether bit size has changed"): 111 assert_param_bits("${getParamPath 2 "foo"}", 1026) 112 113 with subtest("ensure that dhparams file for 'bar' was deleted"): 114 machine.fail("test -e ${getParamPath 1 "bar"}") 115 116 ${switchToGeneration 3} 117 118 with subtest("ensure that 'security.dhparams.path' has been deleted"): 119 machine.fail("test -e ${nodes.machine.config.specialisation.gen3.configuration.security.dhparams.path}") 120 121 ${switchToGeneration 4} 122 123 with subtest("check bit sizes dhparam files"): 124 assert_param_bits( 125 "${getParamPath 4 "foo2"}", 1027 126 ) 127 assert_param_bits( 128 "${getParamPath 4 "bar2"}", 1028 129 ) 130 131 with subtest("check whether dhparam files are in the Nix store"): 132 machine.succeed( 133 "expr match ${getParamPath 4 "foo2"} ${builtins.storeDir}", 134 "expr match ${getParamPath 4 "bar2"} ${builtins.storeDir}", 135 ) 136 137 ${switchToGeneration 5} 138 139 with subtest("check whether defaultBitSize works as intended"): 140 assert_param_bits("${getParamPath 5 "foo3"}", 1029) 141 assert_param_bits("${getParamPath 5 "bar3"}", 1029) 142 ''; 143}