How does caddy choose the certificate for non-SNI hosts?

I have a caddy file that looks something like this:

https://mainhost.example {
    # etc
}

https://www.mainhost.example, https://otherhost.example, https://www.otherhost.example {
    redir 301 {
        / https://mainhost.example{uri}
    }
}

This works great and Let’s Encrypt issues certs fine. However, I would like Caddy to use the certificate for mainhost.example as the certificate if the client does not support SNI. The idea being that the “main” part of the site will still get the right cert if the client does not support SNI. I’m not sure how Caddy decides which certificate to select if the client does not support SNI (which I realize is an admittedly small list of clients these days).

Initial poking it seems to pick a random cert? Sometimes it will pick the cert for mainhost.example as desired, and other times it will pick www.otherhost.example.

I’m using Caddy 0.11.0.

I had previously made the assumption that the certificate used in this case was simply the first certificate in memory (usually the first certificate in the Caddyfile).

I’m not sure which code to look at to verify this one off the top of my head. Perhaps @matt could point us in the right direction.

It’s effectively random, as Go maps are ordered randomly.

First, a TLS config must be selected, this is done by hostname in the SNI: https://sourcegraph.com/github.com/mholt/caddy@73273c5bf81b3962aec314f8b6988cccb7089a5a/-/blob/caddytls/handshake.go#L46-77

Then, the certificate to use is selected using a similar algorithm: https://sourcegraph.com/github.com/mholt/caddy@73273c5bf81b3962aec314f8b6988cccb7089a5a/-/blob/caddytls/handshake.go#L141-206

(The part about TLS-SNI challenge is changing as soon as I finish the PR to implement TLS-ALPN. But the overall behavior will remain the same.)

2 Likes

Thank you for checking, and now I know where some of this functionality lives so I can answer my own other questions.

I’ll direct any thoughts or ways to improve it (if I can think of any… seems like the comments played out all the options) on GitHub.

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