Caddy distributes wrong certificates to hosts without SNI support

1. Caddy version (caddy version):

v2.5.1

2. How I run Caddy:

a. System environment:

Ubuntu 20.04 - 5.4.0-113-generic, I use it as a systemctl service.

d. My complete Caddyfile or JSON config:


{
    auto_https disable_redirects
    default_bind someIP
    admin off
    debug
    https_port 443
    default_sni app1.domain0.fr

}

app1.domain0.fr {
    reverse_proxy localhost:someport

    tls {
        dns cloudflare CLOUDFLAREAPIKEY
    }

    log {
        output file /var/log/caddy/app1.domain0.fr_access.log
    }
}

app2.localdom.local:20443 {
    reverse_proxy localhost:someport

    tls /srv/docker/certs/app2/app2.localdom.local.crt /srv/docker/certs/app2/app2.localdom.local.key {
        ca_root /srv/docker/certs/localdom.local.crt
    }

    log {
        output file /var/log/caddy/app2.localdom.local_access.log
    }
}

app1.localdom.local:20443 {
    reverse_proxy localhost:someport

    tls /srv/docker/certs/app1/app1.localdom.local.crt /srv/docker/certs/app1/app1.localdom.local.key {
        ca_root /srv/docker/certs/localdom.local.crt
    }

    log {
        output file /var/log/caddy/app1.localdom.local_access.log
    }
}

3. The problem I’m having:

With the above configuration I have 4 different sites:

1 site with a routable domain on the internet :

app1.domain0.fr

2 locals sites :

app1.localdom.local
app2.localdom.local

Problem n°1 :

When I access the different sites it works perfectly. My problem is the following: as soon as I access them by the public ip of my server I get an error NET::ERR_CERT_COMMON_NAME_INVALID.

When I look at the certificate distributed by caddy it is the one from app1.localdom.local.

I have the same result using the command

gnutls-cli --disable-sni app1.domain0.fr

I would like that there is no answer from caddy during the requests towards the IP, is it possible?

Problem n°2 :

When I test the security of my website (app1.domain0.fr) with the tool “SSL Server test of Qualys” :
SSL Server Test (Powered by Qualys SSL Labs)

I notice that for the clients not compatible TLS SNI the certificate of app1.localdom.local. is distributed.

Same result when testing a request without TLS SNI with the command :


gnutls-cli --disable-sni app1.domain0.fr

The distributed certificate and always this one of
app1.localdom.local.

Do you have any idea how to solve this problem?

4. Error messages and/or full log output:

I get no error, but I cannot solve my problem…

5. What I already tried:

I try to add this in Caddyfile :


:443 {
  tls internal
  respond * "Access denied" 403 {
	close
  }
}

it result in nothing…
When I access to website using IP, I get app1.localdom.local certifcate error then I accept the warning and I get “Access denied” and the connection is close.

I want the connection to be dropped before caddy send certificate to client.

Thank you in advance for your help, I have tried many configurations but without success.

I don’t think this is an option you should be using – that’s meant to be the ACME CA’s root cert. In this case, you’re not using ACME for your local sites, so this doesn’t make sense. You can remove this.

What do you have in the SAN field for this certificate? If it has app1.domain0.fr in it, then Caddy might select this cert instead of one from ACME.

You don’t need this, it’s redundant. That’s already the default.

Why are you disabling redirects? You’re not serving anything over port 80 otherwise :thinking:

Thank for the fast response.

I was using ca_root because I thought caddy needed the certificate from the certificate authority like most web servers.
This is fixed.

As for my certificates I removed the IP address from the SANs fields. My problem is partially solved.
Now when I access my server from the public IP or private IP caddy gives out the certificate of

app1.domain0.fr

This is not bad, but I would prefer to drop the connection for requests to the private and public IP.

I doubt that this is possible…

As for the http-> https redirection I prefer to disable it and keep only a listening on port 443.

Have you an Idea to drop connection for requests to IP adresses?

Well it does, but the full chain needs to be in your cert file, alongside the leaf cert. That could be part of the issue if the intermediate and root aren’t also in your cert file.

What behaviour are you seeing instead?

1 Like

Thanks for the quick response, it’s cool to have a vibrant and helpful community :slightly_smiling_face:

I Fixe my crt files, it’s logical in reality :expressionless: …

For the request with IP adresses (private or public), I just want to drop all connection.
Currently I get NET::ERR_CERT_COMMON_NAME_INVALID ( certificate chain of app1.domain0.fr ) and when I accept the warning, I get blank page.

1 Like

I’m not sure there’s much else we can do to help as long as you continue to censor your domain. We’d need to see the certificate to actually see what’s going on.

1 Like

my domain : https://jellyfin.mathsyx.fr

Alright, so with that I can see what’s going on, so you mean when requesting https://82.64.155.130/, you get a blank page (after telling the browser to continue). So yeah you’ll need to add this to your config:

https:// {
	abort
}

This should make all connections that don’t match other site blocks have their connections aborted.

1 Like

By removing the general parameter: “default_sni jellyfin.mathsyx.fr” and adding what you suggested, it works !
Thanks for your help, I didn’t want to put my domain for security reasons (caddy version, IP, open port…)

There’s no security benefit. Our forum rules require that you don’t redact:

https://caddy.community/guidelines

1 Like