{ config, lib, pkgs, ... }: with lib; let cfg = config.security.dhparams; in { options = { security.dhparams = { 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 security.dhparams.path/name.pem. 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. 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. ''; type = with types; attrsOf int; default = {}; example = { nginx = 3072; }; }; path = mkOption { description = '' Path to the directory in which Diffie-Hellman parameters will be stored. ''; 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 { 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: value: '' if [ "$file" == "${cfg.path}/${name}.pem" ] && \ ${pkgs.openssl}/bin/openssl dhparam -in "$file" -text | head -n 1 | grep "(${toString value} 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} ''; }; } // mapAttrs' (name: value: 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 value} fi ''; }) cfg.params; }; }