Skip to content

Conversation

mholt
Copy link
Member

@mholt mholt commented Apr 16, 2025

I am refactoring caddytls.TLS.Manage() to take a map[string]struct{} for the list of domains to manage certs for, instead of a []string -- as part of a rethinking of how prefer_wildcard (from #6146) works.

I've been giving this lots of thought, though I probably still have not thought of everything, but it seems to me that prefer_wildcard actually makes more sense at the TLS-app-level, rather than as part of automatic HTTPS in the HTTP app.

See, my reasoning is that many users who want prefer_wildcard -- which I assume is most, but without telemetry, yet again, there's no way to be certain -- want it for two main reasons:

  1. fewer certificates / rate limit avoidance, and
  2. privacy.

The first is a matter of availability, which is crucial, and the second is newly possible with ECH + wildcard certs. We want to try to be private-by-default whenever it is practical & feasible.

Caddy manages certs for more than just HTTPS for sites, so we actually need to bring that logic into the TLS app itself so that we can properly deliver on those two goals: avoiding rate limits and offering privacy. If we only do it for auto-HTTPS, it's not as complete (or correct) of a solution.

So, now, instead of prefer_wildcard -- which was definitely the right idea -- we'll make wildcard coverage the default, then have something like an individual_certificates bool in automation policies that allows users to opt OUT of this coverage, like for subdomains they want to have their own certificates.

And the map makes existence queries for wildcards way faster than iterating a large slice.

This may be surprising for some in that Caddy will no longer get certs for individual subdomains when used as site addresses in the Caddyfile for which there is a wildcard domain specified, but this seems correct most of the time.

This behavior can be overridden by setting individual_certificates: true in the appropriate automation policy, but I haven't yet exposed this to the Caddyfile. @francislavoie -- any thoughts on how we should do this? It could be a global option, i.e. "any subdomains should just always have their own certificates" (which restores the previous behavior), OR we could make it per-site, so only certain subdomains might have their own certificates.

(I know this PR technically rips out the fine code written by @francislavoie -- but I view it as building upon it and finishing it.)


Before (and before prefer_wildcard), you'd need this Caddyfile structure (as documented in our Caddyfile Patterns page) in order to have multiple sites use the same wildcard certificate:

*.example.com {
	tls {
		dns <provider_name> [<params...>]
	}

	@foo host foo.example.com
	handle @foo {
		respond "Foo!"
	}

	@bar host bar.example.com
	handle @bar {
		respond "Bar!"
	}

	# Fallback for otherwise unhandled domains
	handle {
		abort
	}
}

(I actually liked this structure because it was very clear to me what the cert management was doing.)

Now, you can write it like this:

*.example.com {
	tls {
		dns <provider_name> [<params...>]
	}
	abort
}

foo.example.com {
	respond "Foo!"
}

bar.example.com {
	respond "Bar!"
}

Kind of weird to have a route-less site, just for the sake of a wildcard, but whatever. Is this better/cleaner/easier? I dunno.

But from a privacy perspective, I think this PR makes sense. (I guess technically it really needs ECH to be utilized in order for it to make sense. I could make it conditional on ECH being configured? Gets complicated though...)

@mholt mholt added this to the v2.10.0-beta.5 milestone Apr 16, 2025
@mholt mholt requested a review from francislavoie April 16, 2025 23:13
@francislavoie
Copy link
Member

any thoughts on how we should do this?

Well we support tls force_automate in site blocks now, so that could be used to fill individual_certificates I guess.

@mholt
Copy link
Member Author

mholt commented Apr 16, 2025

Good idea.

Can I rename it though? Like, tls individual_cert or something?

@mholt
Copy link
Member Author

mholt commented Apr 17, 2025

@francislavoie I decided to try tls no_wildcard (as in, don't use a wildcard)... what do you think?

@mholt
Copy link
Member Author

mholt commented Apr 18, 2025

Thanks for the discussion in Slack, @francislavoie -- I found the insights very helpful.

I have reverted force_automate to its original behavior, and also removed the IndividualCertificates bool on the automation policy. We now just use the existence of the domain in the "automate" loader as the signal for whether to override the wildcard cert with a subdomain-specific cert.

I also added logic to clean up the adapted JSON config in the case that the Caddyfile would make multiple identical connection policies in a row, only with a single different "sni" matcher hostname. It now combines those policies into one, merging the names in the "sni" matcher.

I think it's ready to merge, let's give it a shot!

@mholt mholt merged commit 1bfa111 into master Apr 18, 2025
20 checks passed
@mholt mholt deleted the prefer-wildcard-default branch April 18, 2025 17:44
@twiesing
Copy link

@mholt:

I wanted to switch my pages to wildcard certificates (Caddy 2.10). Unfortunately, I have only found documentation on this in the issue. Am I blind or is it still missing?

*.example.com {
	tls {
		dns <provider_name> [<params...>]
	}
	abort
}

foo.example.com {
	respond "Foo!"
}

bar.example.com {
	respond "Bar!"
}

@mholt
Copy link
Member Author

mholt commented Apr 23, 2025

I still need to update those docs. That looks correct.

mohammed90 pushed a commit to cedricziel/caddy that referenced this pull request Aug 29, 2025
…ts (caddyserver#6959)

* caddytls: Prefer managed wildcard certs over individual subdomain certs

* Repurpose force_automate as no_wildcard

* Fix a couple bugs

* Restore force_automate and use automate loader as wildcard override
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants