From 03122b43c8380bc8671640e5bbd1aa9fec938b5e Mon Sep 17 00:00:00 2001 From: ThinkChaos Date: Wed, 21 Aug 2024 17:46:49 -0400 Subject: [PATCH] nixos/nginx: not "before" ACME certs using DNS validation Relax dependency with certs that are validated via DNS challenge since we know the HTTP server is not required for that validation. This allows marking the server's service as depending on the cert. --- .../services/web-servers/nginx/default.nix | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 1e43554b7818..848671c16f6f 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -7,7 +7,9 @@ let inherit (config.security.acme) certs; vhostsConfigs = mapAttrsToList (vhostName: vhostConfig: vhostConfig) virtualHosts; acmeEnabledVhosts = filter (vhostConfig: vhostConfig.enableACME || vhostConfig.useACMEHost != null) vhostsConfigs; - dependentCertNames = unique (map (hostOpts: hostOpts.certName) acmeEnabledVhosts); + vhostCertNames = unique (map (hostOpts: hostOpts.certName) acmeEnabledVhosts); + dependentCertNames = filter (cert: certs.${cert}.dnsProvider == null) vhostCertNames; # those that might depend on the HTTP server + independentCertNames = filter (cert: certs.${cert}.dnsProvider != null) vhostCertNames; # those that don't depend on the HTTP server virtualHosts = mapAttrs (vhostName: vhostConfig: let serverName = if vhostConfig.serverName != null @@ -1212,7 +1214,7 @@ in inherit (cfg) group user; cert = config.security.acme.certs.${name}; groups = config.users.groups; - }) dependentCertNames; + }) vhostCertNames; services.nginx.additionalModules = optional cfg.recommendedBrotliSettings pkgs.nginxModules.brotli ++ lib.optional cfg.recommendedZstdSettings pkgs.nginxModules.zstd; @@ -1236,8 +1238,10 @@ in systemd.services.nginx = { description = "Nginx Web Server"; wantedBy = [ "multi-user.target" ]; - wants = concatLists (map (certName: [ "acme-finished-${certName}.target" ]) dependentCertNames); - after = [ "network.target" ] ++ map (certName: "acme-selfsigned-${certName}.service") dependentCertNames; + wants = concatLists (map (certName: [ "acme-finished-${certName}.target" ]) vhostCertNames); + after = [ "network.target" ] + ++ map (certName: "acme-selfsigned-${certName}.service") vhostCertNames + ++ map (certName: "acme-${certName}.service") independentCertNames; # avoid loading self-signed key w/ real cert, or vice-versa # Nginx needs to be started in order to be able to request certificates # (it's hosting the acme challenge after all) # This fixes https://github.com/NixOS/nixpkgs/issues/81842 @@ -1316,8 +1320,8 @@ in # which allows the acme-finished-$cert.target to signify the successful updating # of certs end-to-end. systemd.services.nginx-config-reload = let - sslServices = map (certName: "acme-${certName}.service") dependentCertNames; - sslTargets = map (certName: "acme-finished-${certName}.target") dependentCertNames; + sslServices = map (certName: "acme-${certName}.service") vhostCertNames; + sslTargets = map (certName: "acme-finished-${certName}.target") vhostCertNames; in mkIf (cfg.enableReload || sslServices != []) { wants = optionals cfg.enableReload [ "nginx.service" ]; wantedBy = sslServices ++ [ "multi-user.target" ]; @@ -1329,7 +1333,7 @@ in restartTriggers = optionals cfg.enableReload [ configFile ]; # Block reloading if not all certs exist yet. # Happens when config changes add new vhosts/certs. - unitConfig.ConditionPathExists = optionals (sslServices != []) (map (certName: certs.${certName}.directory + "/fullchain.pem") dependentCertNames); + unitConfig.ConditionPathExists = optionals (sslServices != []) (map (certName: certs.${certName}.directory + "/fullchain.pem") vhostCertNames); serviceConfig = { Type = "oneshot"; TimeoutSec = 60;