An incoming request with the SNI “test.example.com” would match either cert A, B or C (B and C have the exact domain, A has it as a wildcard).
How does haproxy determine which certificate will be sent? Is an exact match (without a wildcard) always preferred? Or is it random (or depends on certificate filename alphabetical ordering)?
Is there a configuration option to always prefer certificate A, if it matches the sent SNI (“test.example.com”)?
My example above only lists certs A+B+C, but in reality there are many more, and everything except cert A is dynamically changing, so they can’t be hard-coded in the configuration without extra trouble.
It seems that crt-list might be the thing I need, but I can’t really understand the documentation.
Basically, I want to specify “always use cert A if it matches the request SNI in any way, and fallback to other certificates only if it doesn’t match.” Can this be done?
strict-sni is only about rejecting handshake requests when there are not SAN matches at all.
As far as I know, exact SAN matches always have priority over wildcard matches.
However a browser may use the same SSL session for additional requests, if the certificate allows, for example if www.example.com matches your wildcard A.pem certificate, if the browser makes a request to test.example.com in H2/H3 it will not restart a new SSL session, instead, because the wild certificate presented earlier covers the hostname. This becomes a problem for SNI based routing.
However, it usually is irrelevant for certificates, because the certificate is valid in all those cases.
Can you elaborate what actual problem you are trying to solve?
The documentation is quite clear and also contains a few examples:
It seems so (in limited testing); thanks for clarifying!
Session reuse is a part of why I would like to optimize the certificate selection; so clients would be provided (if possible) with a wildcard certificate that would also cover future requests. (Put another way: if clients get certificate B, then connection reuse is not possible, as following requests have a domain that would only match certificate A.)
Sorry, I simply couldn’t follow the documentation as written; for example I don’t get how crt-list interacts with crt (are they mutually exclusive?). I can probably figure it out by just trying out various stuff, but then I’m afaid I’ll end up with a configuration that “works for now”, but is not actually correct for future versions, etc…
Anyway, I was hoping there was a “oh, just do X” type of a solution that I couldn’t think of myself. But seems not, so I’ll have to put in the work myself
I will quote the documentation of crt-list I linked above:
This directive [crt-list] may be specified multiple times. See the “crt” option for more information. The default certificate is still needed to meet OpenSSL expectations. If it is not used, the ‘strict-sni’ option may be used.
So in other words, if you specify strict-sni you don’t need crt. Otherwise you will have to specify at least a default certificate.
Well if your are contemplating making complex crt-list overwriting SAN → SNI mapping manually with all the continued effort that this involves on your side especially during renewals, so I have to ask:
Why don’t you just delete the more specific certificate that you don’t want to use?