Skip to content

httpcaddyfile: keep a site block's TLS policy for ECH public names - #8156

Merged
steadytao merged 2 commits into
caddyserver:masterfrom
awss1i:ech-keep-site-policy
Oct 9, 2026
Merged

steadytao merged 2 commits into
caddyserver:masterfrom
awss1i:ech-keep-site-policy

Conversation

@awss1i

@awss1i awss1i commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #7354.

The ech global option adds an automation policy for each public name without checking whether a site block already has one for it. If the site block sets its own TLS options, like tls internal or tls { resolvers ... }, adapting fails with "hostname appears in more than one automation policy". If a hostless catch-all with the same settings is also present, the site's policy is merged away and the name silently gets only the global settings, so a tls internal name was requested from Let's Encrypt.

This skips public names that a site block's policy already covers, matched the way the TLS app picks a policy at runtime, so a wildcard or differently cased subject counts too. It only adds the ECH policy when it still has subjects.

The five new adapt tests fail on master.

Assistance Disclosure

I directed claude code (opus 5.5), which traced the cause, wrote the fix and tests and ran the checks, and I reviewed the code, tests and evidence before posting.

The global ech option added its own automation policy for every public
name, even when a site block already had a policy for that name. If the
site block set its own TLS options, adapting failed with "hostname
appears in more than one automation policy". If a hostless catch-all
with the same settings was also present, the site's policy was merged
away and the name got only the global settings.

Skip public names that already have a policy, as tls_automate_names
does, and only add the ECH policy when it still has subjects, since a
policy without subjects acts as a catch-all.
Comment thread caddyconfig/httpcaddyfile/tlsapp.go Resolved
@francislavoie francislavoie added the bug 🐞 Something isn't working label Oct 8, 2026
@francislavoie francislavoie added this to the v2.12.0 milestone Oct 8, 2026
The check for an existing site policy only matched a subject spelled
exactly like the ECH public name. A site policy for *.example.com, or
for example.com when the public name is written Example.COM, already
covers that name at runtime, but the global ECH policy was still added
and sorted ahead of it, so the site's issuer settings were overridden.

Lowercase and trim the public name as ECH provisioning does and compare
it with certmagic.MatchWildcard, which is how the TLS app picks a policy
for a name.
@steadytao
steadytao merged commit c8591a1 into caddyserver:master Oct 9, 2026
29 checks passed
This was referenced Nov 3, 2026
NickCao pushed a commit to NickCao/caddy that referenced this pull request Nov 4, 2026
…addyserver#8156)

* httpcaddyfile: keep a site block's TLS policy for ECH public names

The global ech option added its own automation policy for every public
name, even when a site block already had a policy for that name. If the
site block set its own TLS options, adapting failed with "hostname
appears in more than one automation policy". If a hostless catch-all
with the same settings was also present, the site's policy was merged
away and the name got only the global settings.

Skip public names that already have a policy, as tls_automate_names
does, and only add the ECH policy when it still has subjects, since a
policy without subjects acts as a catch-all.

* httpcaddyfile: check ECH public names the way the TLS app matches them

The check for an existing site policy only matched a subject spelled
exactly like the ECH public name. A site policy for *.example.com, or
for example.com when the public name is written Example.COM, already
covers that name at runtime, but the global ECH policy was still added
and sorted ahead of it, so the site's issuer settings were overridden.

Lowercase and trim the public name as ECH provisioning does and compare
it with certmagic.MatchWildcard, which is how the TLS app picks a policy
for a name.

(cherry picked from commit c8591a1)
@francislavoie francislavoie modified the milestones: v2.12.0, v2.11.8 Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 🐞 Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Combination of ech and a site block for the ech name cannot use tls resolver config

3 participants