Wrong certification when using my own certificate and letsencrypt certificate

This is my Caddyfile (with some changes to the domains):

http://*.mydomain.me:80 {
    redir 301 {
        /  https://{host}{uri}
https://*.mydomain.me:443 {
    tls /etc/caddy_ssl_efs/ssl_custom/mydomain.pem /etc/caddy_ssl_efs/ssl_custom/mydomain.key

    #proxy / https://mydomain-testing-elasticbeanstalk.mydomain.com {
    #    transparent
    #    header_downstream server "mydomain"

    proxy / localhost:6081 {
        #header_upstream Host "localhost" # Won't work with another value
        header_downstream server "mydomain"

http://* {
    proxy / http://mydomain-testing-elasticbeanstalk.mydomain.com {
        header_downstream server "mydomain"

https://* {
    tls {
        max_certs 500000
    tls noam@mydomain.com
    proxy / localhost:6081 {
        #header_upstream Host "localhost" # Won't work with another value
        header_downstream server "mydomain"

Now the problem is like that:

  • When user enter to this domain: xxxx.mydomain.me he will get the SSL from the server.
  • When user enter to other domain that set under the server www.example.com he sometimes will not get “letsencrypt” domain and he will get xxxx.mydomain.me SSL that of course is not related to him.

If I’m using every part separate and run the server they are getting the right SSL without any problems. The problem is that I want to use this domains on the same server.

Thanks for the help!

Might be that the user in this case is requesting a unique address before the internal cooldown period is met for On-Demand TLS. When that happens, Caddy has to use a ‘default’ certificate to negotiate TLS; the first in the list is the one you provided for *.mydomain.me.

You could set up a server to act as an ask endpoint, instead of using max_certs - this bypasses the ten minute rate limit - and see if the issue persists?

Can you explain this? I’m sorry but I don’t understand what to do

Check out: Automatic HTTPS — Caddy Documentation

The documentation outlines the use and role of an ask endpoint, which you will need to implement in a manner such that it returns 200 OK only for domains that Caddy should request a certificate for.

Then, by replacing max_certs [number] with ask [endpoint], Caddy will ask the endpoint if a client-requested domain is suitable, rather than wait for its one-per-ten-minutes rate limit.

These limitations prevent Caddy instances from being used by malicious actors to reflect huge numbers of bogus ACME challenges against LetsEncrypt’s servers; either the set of potential domains must be bounded (by an ask endpoint) or rate-limited (as it is for max_certs configurations).

Great. I will try it now and let you know

Sorry but this is still happen sometimes. Most of the time he give the right certificate. But sometimes give the mydomain.com

This is very strange and looks like a bug

It would still happen if a unique certificate is requested while another challenge is underway;

  • At most one certificate challenge happens at a time.

Automatic HTTPS — Caddy Documentation

I don’t think there’s any way around this one.

So it’s not solve my issue.
Any why I can tell Caddy to insert the first part of the “mydomain.com” only if the host is “mydomain.com”?
I don’t understand why he enter to this part if the user request other domain name?

I’m making an assumption here that this issue only occurs when the client is requesting a new domain name. If that’s the case, I’d wager that the reason is Caddy decided it’s ineligible for a certificate request, and therefore must fall back on an existing certificate. Since all other certificates are equally invalid, it simply picks the first one available.

If my assumption isn’t correct, it sounds like a bug.

I think that if your is assumption is also correct it’s a bug :slight_smile:

I don’t think that’s the case, because this behaviour is intended. An incoming HTTPS request must have TLS negotiated first before the full request and response can be processed. If all certificates are equally invalid, and one must be provided, the first certificate will suffice. The alternative is to reject the connection, which does not allow for Caddy to serve otherwise valid content, or advise the client that the requested domain is not served.

1 Like

Most of the traffic this days can’t run without right certificate so there is no different.
I think it’s better to tell the user that something is broke and he need to fix it and not give him wrong behaviour that he will not understand what happen.
Caddy don’t need to decide for the user anything. Take a look on my code, I’m telling Caddy what certificate he need to set for every situation. It’s very clear.

We agree that it’s better to tell the user what’s wrong, I think.

Ultimately, serving the “wrong” certificate makes it easier to identify problems such as, for example, when a domain isn’t served at the address; rejecting a connection outright gives troubleshooters far less information, which is why the decision was made.

In your Caddyfile, there is no certificate specified in advance for https://*, so for a request for https://www.example.com - which falls under this site label, because there are no more specific site labels in the Caddyfile for it to match - Caddy must request one from LetsEncrypt. When it can’t do this, we end up with the issue you’re running into.

So after a lot of checks the problem is not only with new domain, but also with existing domains that already have an SSL on the server.
So this is defiantly a bug. Caddy some time enter to the wrong SSL when there is my own SSL and LetsEncrypt SSL on the same Caddyfile.

Hope someone can understand how we can fix it.


Definitely a bug if that’s the case. Go ahead and open up an issue at https://github.com/mholt/caddy/issues, fill out the template, and refer to this thread.

If you have time to narrow it down to the simplest possible reproducible Caddyfile, too, that will help speed up the process. Thanks!

That’s because there is no site in your Caddyfile that matches either of those domains. Wildcards only apply to a single label, so your https://* site, for example, will only match one label like localhost but not foo.local. So, remove the wildcard character.

WOW it’s really solve the problem! Thanks Matt

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.