From 4de774a63bef6d97246641212d8c38cc34ff6665 Mon Sep 17 00:00:00 2001 From: aszlig Date: Thu, 26 Apr 2018 06:09:05 +0200 Subject: nixos/dhparams: Add a VM test We're going to make changes to the dhparams module so we really want to make sure we don't break it, so having a NixOS VM test is to make sure we don't blow things up and can iterate on it. Signed-off-by: aszlig Cc: @Ekleog --- nixos/release.nix | 1 + nixos/tests/dhparams.nix | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 nixos/tests/dhparams.nix (limited to 'nixos') diff --git a/nixos/release.nix b/nixos/release.nix index 2f779280e6b2..9d8a62f99952 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -269,6 +269,7 @@ in rec { tests.containers-macvlans = callTest tests/containers-macvlans.nix {}; tests.couchdb = callTest tests/couchdb.nix {}; tests.deluge = callTest tests/deluge.nix {}; + tests.dhparams = callTest tests/dhparams.nix {}; tests.docker = callTestOnMatchingSystems ["x86_64-linux"] tests/docker.nix {}; tests.docker-tools = callTestOnMatchingSystems ["x86_64-linux"] tests/docker-tools.nix {}; tests.docker-tools-overlay = callTestOnMatchingSystems ["x86_64-linux"] tests/docker-tools-overlay.nix {}; diff --git a/nixos/tests/dhparams.nix b/nixos/tests/dhparams.nix new file mode 100644 index 000000000000..36079b990975 --- /dev/null +++ b/nixos/tests/dhparams.nix @@ -0,0 +1,105 @@ +let + common = { pkgs, ... }: { + security.dhparams.enable = true; + environment.systemPackages = [ pkgs.openssl ]; + }; + +in import ./make-test.nix { + name = "dhparams"; + + nodes.generation1 = { pkgs, config, ... }: { + imports = [ common ]; + security.dhparams.params.foo = 16; + security.dhparams.params.bar = 17; + + systemd.services.foo = { + description = "Check systemd Ordering"; + wantedBy = [ "multi-user.target" ]; + 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.path}/foo.pem"; + }; + 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"; + }; + }; + + nodes.generation2 = { + imports = [ common ]; + security.dhparams.params.foo = 18; + }; + + nodes.generation3 = common; + + testScript = { nodes, ... }: let + getParamPath = gen: name: let + node = "generation${toString gen}"; + inherit (nodes.${node}.config.security.dhparams) path; + in "${path}/${name}.pem"; + + assertParamBits = gen: name: bits: let + path = getParamPath gen name; + in '' + $machine->nest('check bit size of ${path}', sub { + my $out = $machine->succeed('openssl dhparam -in ${path} -text'); + $out =~ /^\s*DH Parameters:\s+\((\d+)\s+bit\)\s*$/m; + die "bit size should be ${toString bits} but it is $1 instead." + if $1 != ${toString bits}; + }); + ''; + + switchToGeneration = gen: let + node = "generation${toString gen}"; + inherit (nodes.${node}.config.system.build) toplevel; + switchCmd = "${toplevel}/bin/switch-to-configuration test"; + in '' + $machine->nest('switch to generation ${toString gen}', sub { + $machine->succeed('${switchCmd}'); + $main::machine = ''$${node}; + }); + ''; + + in '' + my $machine = $generation1; + + $machine->waitForUnit('multi-user.target'); + + subtest "verify startup order", sub { + $machine->succeed('systemctl is-active foo.service'); + }; + + subtest "check bit sizes of dhparam files", sub { + ${assertParamBits 1 "foo" 16} + ${assertParamBits 1 "bar" 17} + }; + + ${switchToGeneration 2} + + subtest "check whether bit size has changed", sub { + ${assertParamBits 2 "foo" 18} + }; + + subtest "ensure that dhparams file for 'bar' was deleted", sub { + $machine->fail('test -e ${getParamPath 1 "bar"}'); + }; + + ${switchToGeneration 3} + + subtest "ensure that 'security.dhparams.path' has been deleted", sub { + $machine->fail( + 'test -e ${nodes.generation3.config.security.dhparams.path}' + ); + }; + ''; +} -- cgit 1.4.1 From 761266bd18cf1117a11d2fd6168259f7fe867122 Mon Sep 17 00:00:00 2001 From: aszlig Date: Thu, 26 Apr 2018 06:19:48 +0200 Subject: 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 and . 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 Cc: @Ekleog --- nixos/modules/security/dhparams.nix | 64 +++++++++++++++++++++++++++---------- nixos/tests/dhparams.nix | 16 ++++++---- 2 files changed, 57 insertions(+), 23 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/security/dhparams.nix b/nixos/modules/security/dhparams.nix index 55c75713101d..7c9fe986e576 100644 --- a/nixos/modules/security/dhparams.nix +++ b/nixos/modules/security/dhparams.nix @@ -1,10 +1,38 @@ { config, lib, pkgs, ... }: with lib; + let 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 + . + ''; + }; + + config.path = "${cfg.path}/${name}.pem"; + }; + +in { options = { security.dhparams = { params = mkOption { @@ -14,21 +42,23 @@ in The value is the size (in bits) of the DH params to generate. The generated DH params path can be found in - security.dhparams.path/name.pem. + config.security.dhparams.params.name.path. - Note: The name of the DH params is taken as being the name of the - service it serves: the params will be generated before the said - service is started. + 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. - Warning: If you are removing all dhparams from this list, you have - to leave security.dhparams.enable 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. + 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. ''; - type = with types; attrsOf int; + type = with types; let + coerce = bits: { inherit bits; }; + in attrsOf (coercedTo types.int coerce (submodule paramsSubmodule)); default = {}; - example = { nginx = 3072; }; + example = literalExample "{ nginx.bits = 3072; }"; }; path = mkOption { @@ -71,10 +101,10 @@ in if [ ! -f "$file" ]; then continue fi - '' + concatStrings (mapAttrsToList (name: value: + '' + concatStrings (mapAttrsToList (name: { bits, ... }: '' 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 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"; after = [ "dhparams-init.service" ]; before = [ "${name}.service" ]; @@ -99,7 +129,7 @@ in '' mkdir -p ${cfg.path} 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 ''; }) cfg.params; diff --git a/nixos/tests/dhparams.nix b/nixos/tests/dhparams.nix index 36079b990975..ead5f2efce7c 100644 --- a/nixos/tests/dhparams.nix +++ b/nixos/tests/dhparams.nix @@ -9,8 +9,13 @@ in import ./make-test.nix { nodes.generation1 = { pkgs, config, ... }: { imports = [ common ]; - security.dhparams.params.foo = 16; - security.dhparams.params.bar = 17; + security.dhparams.params = { + # 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 = { description = "Check systemd Ordering"; @@ -22,7 +27,7 @@ in import ./make-test.nix { DefaultDependencies = false; # 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.RemainAfterExit = true; @@ -37,7 +42,7 @@ in import ./make-test.nix { nodes.generation2 = { imports = [ common ]; - security.dhparams.params.foo = 18; + security.dhparams.params.foo.bits = 18; }; nodes.generation3 = common; @@ -45,8 +50,7 @@ in import ./make-test.nix { testScript = { nodes, ... }: let getParamPath = gen: name: let node = "generation${toString gen}"; - inherit (nodes.${node}.config.security.dhparams) path; - in "${path}/${name}.pem"; + in nodes.${node}.config.security.dhparams.params.${name}.path; assertParamBits = gen: name: bits: let path = getParamPath gen name; -- cgit 1.4.1 From 3e11ff6e0d9fb21a962408407f24b465b30fe96f Mon Sep 17 00:00:00 2001 From: aszlig Date: Thu, 26 Apr 2018 06:38:02 +0200 Subject: 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 Cc: @Ekleog, @abbradar, @fpletz --- nixos/modules/security/dhparams.nix | 39 +++++++++++++++++++++++++++++-------- nixos/tests/dhparams.nix | 21 ++++++++++++++++++++ 2 files changed, 52 insertions(+), 8 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/security/dhparams.nix b/nixos/modules/security/dhparams.nix index 7c9fe986e576..64b296eea5b8 100644 --- a/nixos/modules/security/dhparams.nix +++ b/nixos/modules/security/dhparams.nix @@ -29,7 +29,11 @@ let ''; }; - config.path = "${cfg.path}/${name}.pem"; + config.path = let + generated = pkgs.runCommand "dhparams-${name}.pem" { + nativeBuildInputs = [ pkgs.openssl ]; + } "openssl dhparam -out \"$out\" ${toString config.bits}"; + in if cfg.stateful then "${cfg.path}/${name}.pem" else generated; }; in { @@ -52,7 +56,9 @@ in { 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. + existing ones won't be cleaned up. Of course this only applies if + is + true. ''; type = with types; let coerce = bits: { inherit bits; }; @@ -61,12 +67,29 @@ in { example = literalExample "{ nginx.bits = 3072; }"; }; + stateful = mkOption { + type = types.bool; + default = true; + description = '' + Whether generation of Diffie-Hellman parameters should be stateful or + not. If this is enabled, PEM-encoded files for Diffie-Hellman + parameters are placed in the directory specified by + . Otherwise the files are + created within the Nix store. + + If this is false the resulting store + path will be non-deterministic and will be rebuilt every time the + openssl package changes. + ''; + }; + path = mkOption { - description = - '' - Path to the directory in which Diffie-Hellman parameters will be - stored. - ''; + 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"; }; @@ -82,7 +105,7 @@ in { }; }; - config = mkIf cfg.enable { + config = mkIf (cfg.enable && cfg.stateful) { systemd.services = { dhparams-init = { description = "Cleanup old Diffie-Hellman parameters"; diff --git a/nixos/tests/dhparams.nix b/nixos/tests/dhparams.nix index ead5f2efce7c..da75391e4ce5 100644 --- a/nixos/tests/dhparams.nix +++ b/nixos/tests/dhparams.nix @@ -47,6 +47,13 @@ in import ./make-test.nix { nodes.generation3 = common; + nodes.generation4 = { + imports = [ common ]; + security.dhparams.stateful = false; + security.dhparams.params.foo2.bits = 18; + security.dhparams.params.bar2.bits = 19; + }; + testScript = { nodes, ... }: let getParamPath = gen: name: let node = "generation${toString gen}"; @@ -105,5 +112,19 @@ in import ./make-test.nix { 'test -e ${nodes.generation3.config.security.dhparams.path}' ); }; + + ${switchToGeneration 4} + + subtest "check bit sizes dhparam files", sub { + ${assertParamBits 4 "foo2" 18} + ${assertParamBits 4 "bar2" 19} + }; + + subtest "check whether dhparam files are in the Nix store", sub { + $machine->succeed( + 'expr match ${getParamPath 4 "foo2"} ${builtins.storeDir}', + 'expr match ${getParamPath 4 "bar2"} ${builtins.storeDir}', + ); + }; ''; } -- cgit 1.4.1 From ce8777386786f5a38fb0bc8728515a66c82c3d04 Mon Sep 17 00:00:00 2001 From: aszlig Date: Thu, 26 Apr 2018 07:11:54 +0200 Subject: nixos/dhparams: Clean up module expression First of all let's start with a clean up the multiline string indentation for descriptions, because having two indentation levels after description is a waste of screen estate. A quick survey in the form of the following also reveals that the majority of multiline strings in nixpkgs is starting the two beginning quotes in the same line: $ find -name '*.nix' -exec sed -n -e '/=$/ { n; /'\'\''/p }' {} + | wc -l 817 $ find -name '*.nix' -exec grep "= *'' *\$" {} + | wc -l 14818 The next point is to get the type, default and example attributes on top of the description because that's the way it's rendered in the manual. Most services have their enable option close to the beginning of the file, so let's move it to the top. Also, I found the script attribute for dhparams-init.service a bit hard to read as it was using string concatenation to split a "for" loop. Now for the more substantial clean ups rather than just code style: * Remove the "with lib;" at the beginning of the module, because it makes it easier to do a quick check with "nix-instantiate --parse". * Use ConditionPathExists instead of test -e for checking whether we need to generate the dhparams file. This avoids spawning a shell if the file exists already and it's probably more common that it will exist, except for the initial creation of course. * When cleaning up old dhparams file, use RemainAfterExit so that the unit won't be triggered again whenever we stop and start a service depending on it. * Capitalize systemd unit descriptions to be more in par with most other unit descriptions (also see 0c5e837b66f58265ce2b66a33d0f47a3). * Use "=" instead of "==" for conditionals using []. It's just a very small nitpick though and it will only fail for POSIX shells. Bash on the other side accepts it anyway. Signed-off-by: aszlig Cc: @Ekleog --- nixos/modules/security/dhparams.nix | 154 ++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 79 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/security/dhparams.nix b/nixos/modules/security/dhparams.nix index 64b296eea5b8..481d4c5db512 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 + description = "Clean Up Old Diffie-Hellman Parameters"; + + # Clean up even when no DH params is set + wantedBy = [ "multi-user.target" ]; + + serviceConfig.RemainAfterExit = true; serviceConfig.Type = "oneshot"; - script = - # Create directory - '' - if [ ! -d ${cfg.path} ]; then - mkdir -p ${cfg.path} - fi - '' + + + script = '' + 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 + for file in ${cfg.path}/*; do + if [ ! -f "$file" ]; then + continue + fi + ${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} - ''; + '') 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} + ''; }; - } // - 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" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig.Type = "oneshot"; - script = - '' - mkdir -p ${cfg.path} - if [ ! -f ${cfg.path}/${name}.pem ]; then - ${pkgs.openssl}/bin/openssl dhparam -out ${cfg.path}/${name}.pem ${toString bits} - fi - ''; - }) cfg.params; + } // 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; }; } -- cgit 1.4.1 From b3d5ca8359d3fac0f21ccece79c202557a9433b5 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 30 Apr 2018 05:53:38 +0200 Subject: nixos/dhparams: Set default bit size to 2048 @Ekleog writes in https://github.com/NixOS/nixpkgs/pull/39526: > I think a default of 4096 is maybe too much? See certbot/certbot#4973; > Let's Encrypt supposedly know what they are doing and use a > pre-generated 2048-bit DH params (and using the same DH params as > others is quite bad, even compared to lower bit size, if I correctly > remember the attacks available -- because it increases by as much the > value of breaking the group). > Basically I don't have anything personal against 4096, but fear it may > re-start the arms race: people like having "more security" than their > distributions, and having NixOS already having more security than is > actually useful (I personally don't know whether a real-size quantum > computer will come before or after our being able to break 2048-bit > keys, let alone 3072-bit ones -- see wikipedia for some numbers). > So basically, I'd have set it to 3072 in order to both decrease build > time and avoid having people setting it to 8192 and complaining about > how slow things are, but that's just my opinion. :) While he suggests is 3072 I'm using 2048 now, because it's the default of "openssl dhparam". If users want to have a higher value, they can still change it. Signed-off-by: aszlig --- nixos/modules/security/dhparams.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nixos') diff --git a/nixos/modules/security/dhparams.nix b/nixos/modules/security/dhparams.nix index 481d4c5db512..beac125fc6e0 100644 --- a/nixos/modules/security/dhparams.nix +++ b/nixos/modules/security/dhparams.nix @@ -10,7 +10,7 @@ let name = "bits"; description = "integer of at least 16 bits"; }; - default = 4096; + default = 2048; description = '' The bit size for the prime that is used during a Diffie-Hellman key exchange. -- cgit 1.4.1 From 81fc2c35097f81ecb29a576148486cc1ce5a5bcc Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 7 May 2018 04:33:56 +0200 Subject: nixos/dhparams: Add a defaultBitSize option This allows to set the default bit size for all the Diffie-Hellman parameters defined in security.dhparams.params and it's particularly useful so that we can set it to a very low value in tests (so it doesn't take ages to generate). Regardless for the use in testing, this also has an impact in production systems if the owner wants to set all of them to a different size than 2048, they don't need to set it individually for every params that are set. I've added a subtest to the "dhparams" NixOS test to ensure this is working properly. Signed-off-by: aszlig --- nixos/modules/security/dhparams.nix | 27 ++++++++++++++++++++++----- nixos/tests/dhparams.nix | 14 ++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) (limited to 'nixos') diff --git a/nixos/modules/security/dhparams.nix b/nixos/modules/security/dhparams.nix index beac125fc6e0..e2b84c3e3b38 100644 --- a/nixos/modules/security/dhparams.nix +++ b/nixos/modules/security/dhparams.nix @@ -4,13 +4,15 @@ let inherit (lib) mkOption types; cfg = config.security.dhparams; + bitType = types.addCheck types.int (b: b >= 16) // { + name = "bits"; + description = "integer of at least 16 bits"; + }; + paramsSubmodule = { name, config, ... }: { options.bits = mkOption { - type = types.addCheck types.int (b: b >= 16) // { - name = "bits"; - description = "integer of at least 16 bits"; - }; - default = 2048; + type = bitType; + default = cfg.defaultBitSize; description = '' The bit size for the prime that is used during a Diffie-Hellman key exchange. @@ -70,6 +72,11 @@ in { existing ones won't be cleaned up. Of course this only applies if is true. + + For module implementers:It's recommended + to not set a specific bit size here, so that users can easily + override this by setting + . ''; }; @@ -89,6 +96,16 @@ in { ''; }; + defaultBitSize = mkOption { + type = bitType; + default = 2048; + description = '' + This allows to override the default bit size for all of the + Diffie-Hellman parameters set in + . + ''; + }; + path = mkOption { type = types.str; default = "/var/lib/dhparams"; diff --git a/nixos/tests/dhparams.nix b/nixos/tests/dhparams.nix index da75391e4ce5..d11dfeec5d0c 100644 --- a/nixos/tests/dhparams.nix +++ b/nixos/tests/dhparams.nix @@ -54,6 +54,13 @@ in import ./make-test.nix { security.dhparams.params.bar2.bits = 19; }; + nodes.generation5 = { + imports = [ common ]; + security.dhparams.defaultBitSize = 30; + security.dhparams.params.foo3 = {}; + security.dhparams.params.bar3 = {}; + }; + testScript = { nodes, ... }: let getParamPath = gen: name: let node = "generation${toString gen}"; @@ -126,5 +133,12 @@ in import ./make-test.nix { 'expr match ${getParamPath 4 "bar2"} ${builtins.storeDir}', ); }; + + ${switchToGeneration 5} + + subtest "check whether defaultBitSize works as intended", sub { + ${assertParamBits 5 "foo3" 30} + ${assertParamBits 5 "bar3" 30} + }; ''; } -- cgit 1.4.1 From a8b7372380725af56c213cdb01893640d5097c16 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 7 May 2018 05:02:41 +0200 Subject: nixos: Add release notes about dhparams changes This is not only to make users aware of the changes but also to give a heads up to developers which are using the module. Specifically if they rely on security.dhparams.path only. Signed-off-by: aszlig --- nixos/doc/manual/release-notes/rl-1809.xml | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'nixos') diff --git a/nixos/doc/manual/release-notes/rl-1809.xml b/nixos/doc/manual/release-notes/rl-1809.xml index 61f9ec8ba995..acf9db8f3e3f 100644 --- a/nixos/doc/manual/release-notes/rl-1809.xml +++ b/nixos/doc/manual/release-notes/rl-1809.xml @@ -77,7 +77,57 @@ following incompatible changes: + The module for has two new options + now: + + + + + + Puts the generated Diffie-Hellman parameters into the Nix store + instead of managing them in a stateful manner in + /var/lib/dhparams. + + + + + + The default bit size to use for the generated Diffie-Hellman + parameters. + + + + + + The path to the actual generated parameter files should now be queried + using + config.security.dhparams.params.name.path + because it might be either in the Nix store or in a directory configured + by . + + + + For developers: + + Module implementers should not set a specific bit size in order to let + users configure it by themselves if they want to have a different bit + size than the default (2048). + + + An example usage of this would be: + +{ config, ... }: + +{ + security.dhparams.params.myservice = {}; + environment.etc."myservice.conf".text = '' + dhparams = ${config.security.dhparams.params.myservice.path} + ''; +} + + + -- cgit 1.4.1