From b99d3a4f8be2b53046b2b2c4a22c72236c0d4f2d Mon Sep 17 00:00:00 2001 From: ThinkChaos Date: Wed, 21 Aug 2024 17:46:30 -0400 Subject: [PATCH] nixos/apache: 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. --- .../web-servers/apache-httpd/default.nix | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix index 46cb09959579..e64fbff00fd5 100644 --- a/nixos/modules/services/web-servers/apache-httpd/default.nix +++ b/nixos/modules/services/web-servers/apache-httpd/default.nix @@ -33,7 +33,9 @@ let certName = if hostOpts.useACMEHost != null then hostOpts.useACMEHost else hostOpts.hostName; }) (filter (hostOpts: hostOpts.enableACME || hostOpts.useACMEHost != null) vhosts); - 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 mkListenInfo = hostOpts: if hostOpts.listen != [] then @@ -644,7 +646,7 @@ in inherit (cfg) group user; cert = config.security.acme.certs.${name}; groups = config.users.groups; - }) dependentCertNames; + }) vhostCertNames; warnings = mapAttrsToList (name: hostOpts: '' @@ -747,8 +749,10 @@ in systemd.services.httpd = { description = "Apache HTTPD"; 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 before = map (certName: "acme-${certName}.service") dependentCertNames; restartTriggers = [ cfg.configFile ]; @@ -789,8 +793,8 @@ in # which allows the acme-finished-$cert.target to signify the successful updating # of certs end-to-end. systemd.services.httpd-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 (sslServices != []) { wantedBy = sslServices ++ [ "multi-user.target" ]; # Before the finished targets, after the renew services. @@ -801,7 +805,7 @@ in restartTriggers = [ cfg.configFile ]; # Block reloading if not all certs exist yet. # Happens when config changes add new vhosts/certs. - unitConfig.ConditionPathExists = map (certName: certs.${certName}.directory + "/fullchain.pem") dependentCertNames; + unitConfig.ConditionPathExists = map (certName: certs.${certName}.directory + "/fullchain.pem") vhostCertNames; serviceConfig = { Type = "oneshot"; TimeoutSec = 60;