Skip to content
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

Certificate for catch-all site is used for requests to other sites #5933

Open
SimJoSt opened this issue Nov 7, 2023 · 10 comments
Open

Certificate for catch-all site is used for requests to other sites #5933

SimJoSt opened this issue Nov 7, 2023 · 10 comments
Labels
bug 🐞 Something isn't working help wanted 🆘 Extra attention is needed

Comments

@SimJoSt
Copy link

SimJoSt commented Nov 7, 2023

The issue is that the certificate loaded via the tls directive from files in the second site block for website2, containing a catch-all, is used for all request to caddy. Only the certificate is used.
The content is still used from the requested domain/site/block. Meaning, each request returns the wanted content from the requested application, just the certificate is from completely different site block.

For example, https://subdomain.website1.com returns certificate 2, when certificate 1 is expected.
Expected behaviour would be:

  • https://subdomain.website1.com -> certificate 1
  • https://www.website1.com -> certificate 2
  • https://www.website2.com -> certificate 2
  • https://www.example.com -> certificate 2
  • https://test.website2.com -> certificate 2
    However, certificate 2 is returned every time.

Caddy is only hit with https requests. http requests or http to https redirects don't play a role.

The following docs lead me to believe, I configured this correctly and like it was intended:

Things that were tried:

  • replacing :443 with https://
  • switching the import order in the main Caddyfile

Main Caddyfile:

import /home/deployer/website1/Caddyfile
import /home/deployer/website2/Caddyfile

website1 Caddyfile (uses automatic https, no tls directive is configured):

subdomain.website1.com {
    ...
}

website2 Caddyfile:

www.website2.com,
*.website2.com,
:443 {
    tls cert.pem key.pem
    ...
}

Caddy version: v2.7.5
Modules:

@SimJoSt
Copy link
Author

SimJoSt commented Nov 7, 2023

Had an oversight and missed a debugging step. Will close for now, until more accurate information is available.

@SimJoSt SimJoSt closed this as not planned Won't fix, can't repro, duplicate, stale Nov 7, 2023
@francislavoie francislavoie added the invalid ❓ This doesn't seem right label Nov 7, 2023
@SimJoSt SimJoSt changed the title Catch-all site captures all requests, even more specific site selectors are present Certificate for catch-all site is used for requests to other sites Nov 7, 2023
@SimJoSt
Copy link
Author

SimJoSt commented Nov 7, 2023

Finished up the missing debugging and adjusted the content, information, explanation, and title of the issue. Hopefully, I expressed this edge-case clearly and in a helpful way.
@francislavoie it would be lovely if you could remove the "invalid" tag 🙏

@SimJoSt SimJoSt reopened this Nov 7, 2023
@SimJoSt
Copy link
Author

SimJoSt commented Nov 7, 2023

I also tried to add a simple tls directive to the site blocks that didn't have any before:

tls email@example.com

Unfortunately, this didn't resolve the issue.

@mholt mholt removed the invalid ❓ This doesn't seem right label Nov 7, 2023
@mholt
Copy link
Member

mholt commented Nov 9, 2023

Thanks, will look into this soon! (A little busy with new baby, heh)

@SimJoSt
Copy link
Author

SimJoSt commented Nov 12, 2023

Sounds great! Both of the statements. So, congratulations.
And I hope I am not wasting your time with a configuration mistake. If you need any additional information, tests or debugging, I am happy to do so.
I can add that the wildcard site uses a Cloudflare origin server certificate, while the others are on automatic tls from Caddy.

@francislavoie
Copy link
Member

You might need to play with auto_https ignore_loaded_certificates global option https://caddyserver.com/docs/caddyfile/options#auto-https it might solve your problem.

@Matthieu-LAURENT39
Copy link

Matthieu-LAURENT39 commented Nov 19, 2023

Same issue here, i have my Caddyfile configured like this

{
        admin "unix//run/caddy/admin.socket"
        email contact@example.com
        auto_https disable_redirects
}


subdomain.example.com {
    reverse_proxy localhost:4500
}


*.example.com {
        tls internal

        @somesite host somesite.example.com
        handle @somesite {
                reverse_proxy 127.0.0.1:48767
        }

        handle {
                respond "That's a non-existant page!"
        }
}

anothersubdomain.example.com {
    reverse_proxy localhost:8080
}

:2020 {
    root * /opt/webservice
    file_server
}

Unfortunately, subdomain.example.com ends up being served by the local self-signed certificate.
Commenting out tls internal in the wildcard block makes it work, but obviously that's not a viable solution as i need it to be self-signed.
Even weirder though, if i comment out the :2020 block (even without tls internal commented out), then it also starts using the correct certificate again for subdomain.example.com

This happens on 2.7.5, and on all older versions i tested (i tested down to 2.5.2)

@mholt mholt added help wanted 🆘 Extra attention is needed bug 🐞 Something isn't working labels Nov 20, 2023
@SimJoSt
Copy link
Author

SimJoSt commented Nov 22, 2023

You might need to play with auto_https ignore_loaded_certificates global option caddyserver.com/docs/caddyfile/options#auto-https it might solve your problem.

I tried out auto_https ignore_loaded_certs as a global option, validated the config, reloaded it and tried again. No dice.
Seems like the issue is deeply rooted.

Maybe it's also because the Subject of the Cloudflare Origin Server Certificate is

CN = CloudFlare Origin Certificate
OU = CloudFlare Origin CA
O = CloudFlare, Inc.

Not the main domain, as it is usually the case.
The alternative name is

website2.com
*.website2.com

@SimJoSt
Copy link
Author

SimJoSt commented Feb 15, 2024

As a workaround we switched all hosted sites to using Cloudflares Origin Certificates and the one site that isn't using them doesn't have strict checking of certificates enabled, which also works.
However, it is a real shame that this case is broken this badly. If we wouldn't use Cloudflare as a proxy in front of it, we wouldn't have any recourse.

Edit: As long as we know the domains that need to be accepted by the site before the first request, we could also use the REST API to add them on the fly. This is the case for us, as customers register them in the application and we send to Cloudflare for SaaS via the API.
Not every setup might have this advantage though.

@mholt
Copy link
Member

mholt commented Feb 15, 2024

Thanks for the update. Sorry I've been very behind. Turns out an early baby can set you back a few months :) Someone else is welcome to tackle this for a faster resolution.

What I'd suggest doing is getting the JSON config, examining it to see if there's an obvious reason why this might be happening. If not, then sprinkle some log.Println() lines in relevant paths in the caddytls package or in CertMagic (handshake.go would be a good place to start). CertMagic actually powers the certificate cache and selection logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working help wanted 🆘 Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants