-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong certificate when mixing on-demand and manual TLS #1991
Comments
Hey Filippo, thanks for the report. I'll take a look at this. What are all the names (CommonName and/or SAN) on the certificate in |
Aha, your intuition is correct, (You can see it live at https://whoami.filippo.io) |
Excellent: I understand the nature of this bug now. This was a fix for a bug reported on the forums related to OCSP stapling. See #1821. But apparently this is problematic. Hmm. We will need to find another way to prevent overlapping names while preserving OCSP stapling correctness and serving the right certificates... |
Yeah, you’ll probably have to key OCSP caches by certificate fingerprint. |
Or, right now Caddy uses a single, global certificate cache. I wonder if the certificate cache should be divided up by site. In other words, each site uses a separate cert cache, and to maintain certificates I just keep a list of cert caches to iterate through (one more Trying to think if this will have any negative consequences. (I should probably beef up testing around this after the fires are out.) Also need to find out if the overlap prevention would be needed if dividing the cert caches up. |
That also sounds good, in these (Confirmed that removing |
Cool. Thanks for your help. And yeah, the I also need to find out if/how this will affect config reloads. I'll try to get on this today after church 😇 . |
Alright, I think I can boil it down to this: A handshake comes in for some site,
Suppose both those sites have different TLS certificates for some reason. Which one should be loaded? I think I can fix the bug you've reported, but we need to decide how to handle this situation. There may be others; I'm just banging on the dents I can find so far. |
IMHO if those two sites have different TLS configurations it’s a
configuration error and Caddy should not start.
|
Hmm, I think I agree. I will try to figure out the best way to implement this next. |
- Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
@mholt Sorry for not testing this earlier, but the latest version seems to fix the issue! Thank you! |
I am super relieved. :) |
1. What version of Caddy are you using (
caddy -version
)?2. What are you trying to do?
Serving both a manual certificate and a Let's Encrypt certificate on two different domains.
3. What is your entire Caddyfile?
4. How did you run Caddy (give the full command and describe the execution environment)?
6. What did you expect to see?
Let's Encrypt on whoami.filippo.io, my custom certificate on ticketbleed.filippo.io and cve-2016-2107.filippo.io.
7. What did you see instead (give full error messages and/or log)?
The custom certificate is served on whoami.filippo.io.
Even if I deleted the ACME certificate, Caddy obtained a new (correct) one and placed it at
/etc/caddy/.caddy/acme/acme-v01.api.letsencrypt.org/sites/whoami.filippo.io/whoami.filippo.io.crt
while starting. However it then doesn't use it.This is a regression, the previous version (alas lost to the wind) was working correctly.
The text was updated successfully, but these errors were encountered: