From 0badb071efc38bb9cc055076f0a48d1725fe8cc8 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Mon, 4 Aug 2025 16:20:49 -0600 Subject: [PATCH] httpcaddyfile: Fix generated config related to ACME global options If global DNS provider is configured, it does not need to be repeated in the JSON. If acme_* options are used, base automation policies should populate their issuers accordingly. Global issuer settings like acme_* options don't need to specify subjects in the automation policy since they should apply as a global default. --- caddyconfig/httpcaddyfile/tlsapp.go | 22 +++++++++++++++++-- ...e_dns_naked_use_dns_defaults.caddyfiletest | 9 +------- ...bal_options_preferred_chains.caddyfiletest | 3 --- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/caddyconfig/httpcaddyfile/tlsapp.go b/caddyconfig/httpcaddyfile/tlsapp.go index df56f3825..65128efd6 100644 --- a/caddyconfig/httpcaddyfile/tlsapp.go +++ b/caddyconfig/httpcaddyfile/tlsapp.go @@ -571,6 +571,10 @@ func fillInGlobalACMEDefaults(issuer certmagic.Issuer, options map[string]any) e return fmt.Errorf("acme_dns specified without DNS provider config, but no provider specified with 'dns' global option") } } + acmeIssuer.Challenges = &caddytls.ChallengesConfig{ + DNS: new(caddytls.DNSChallengeConfig), + } + } else if globalACMEDNS != nil { acmeIssuer.Challenges = &caddytls.ChallengesConfig{ DNS: &caddytls.DNSChallengeConfig{ ProviderRaw: caddyconfig.JSONModuleObject(globalACMEDNS, "name", globalACMEDNS.(caddy.Module).CaddyModule().ID.Name(), nil), @@ -622,12 +626,18 @@ func newBaseAutomationPolicy( _, hasLocalCerts := options["local_certs"] keyType, hasKeyType := options["key_type"] ocspStapling, hasOCSPStapling := options["ocsp_stapling"] - hasGlobalAutomationOpts := hasIssuers || hasLocalCerts || hasKeyType || hasOCSPStapling + globalACMECA := options["acme_ca"] + globalACMECARoot := options["acme_ca_root"] + _, globalACMEDNS := options["acme_dns"] // can be set to nil (to use globally-defined "dns" value instead), but it is still set + globalACMEEAB := options["acme_eab"] + globalPreferredChains := options["preferred_chains"] + hasGlobalACMEDefaults := globalACMECA != nil || globalACMECARoot != nil || globalACMEDNS || globalACMEEAB != nil || globalPreferredChains != nil + // if there are no global options related to automation policies // set, then we can just return right away - if !hasGlobalAutomationOpts { + if !hasGlobalAutomationOpts && !hasGlobalACMEDefaults { if always { return new(caddytls.AutomationPolicy), nil } @@ -649,6 +659,14 @@ func newBaseAutomationPolicy( ap.Issuers = []certmagic.Issuer{new(caddytls.InternalIssuer)} } + if hasGlobalACMEDefaults { + for i := range ap.Issuers { + if err := fillInGlobalACMEDefaults(ap.Issuers[i], options); err != nil { + return nil, fmt.Errorf("filling in global issuer defaults for issuer %d: %v", i, err) + } + } + } + if hasOCSPStapling { ocspConfig := ocspStapling.(certmagic.OCSPConfig) ap.DisableOCSPStapling = ocspConfig.DisableStapling diff --git a/caddytest/integration/caddyfile_adapt/acme_dns_naked_use_dns_defaults.caddyfiletest b/caddytest/integration/caddyfile_adapt/acme_dns_naked_use_dns_defaults.caddyfiletest index 3fcca9340..750ba22a4 100644 --- a/caddytest/integration/caddyfile_adapt/acme_dns_naked_use_dns_defaults.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/acme_dns_naked_use_dns_defaults.caddyfiletest @@ -34,17 +34,10 @@ example.com { "automation": { "policies": [ { - "subjects": [ - "example.com" - ], "issuers": [ { "challenges": { - "dns": { - "provider": { - "name": "mock" - } - } + "dns": {} }, "module": "acme" } diff --git a/caddytest/integration/caddyfile_adapt/global_options_preferred_chains.caddyfiletest b/caddytest/integration/caddyfile_adapt/global_options_preferred_chains.caddyfiletest index 1f5d0093e..e910a3d7e 100644 --- a/caddytest/integration/caddyfile_adapt/global_options_preferred_chains.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/global_options_preferred_chains.caddyfiletest @@ -31,9 +31,6 @@ example.com "automation": { "policies": [ { - "subjects": [ - "example.com" - ], "issuers": [ { "module": "acme",