I cannot renew the certficate for one of my apache2 virtual hosts, because letsencrypt (obviously) does not use the certificate retrieved when using tls-sni-01. Here’s what I get:
- The following errors were reported by the server:
Domain: ks.eit.h-da.de
Type: unauthorized
Detail: Incorrect validation certificate for tls-sni-01 challenge.
Requested d976adad886868faf3e975a2c206d029.88bbaeb709da69d0294919b6
ffd5c2d6.acme.invalid from 141.100.108.233:443. Received 2
certificate(s), first certificate had names "cypht.eit.h-da.de"
Now, when I look at ssllabs’ analyses, I find that the certificate for cypht.eit.h-da.de is indeed returned, but only when not using SNI: “only very old clients get this certificate”. Why does letsencrypt behave like a very old client, i.e. use the certificate returned when not using SNI?
(Note: ssllabs shows the certificate for “cypht.eit.h-da.de” also when testing my other virtual hosts, but I never had renewal problems with those.)
Well, any idea what could cause this in apache? As mentioned, there are several virtual hosts and only this one causes problems.
But I’m still not convinced that this is caused by apache. It works with the other virtual hosts and they obviously also report the redundant certificate.
thanks a lot for the hints. But I’m still confused. Because openssl s_client -connect ks.eit.h-da.de:443 -servername ks.eit.h-da.dedoes return the proper certificate:
Given a Challenge/Response pair, the ACME server verifies the
client’s control of the domain by verifying that the TLS server was
configured appropriately.
Given a Challenge/Response pair, the ACME server verifies the
client’s control of the domain by verifying that the TLS server was
configured appropriately.
Choose a subset of the N iterations to check, according to local
policy.
For each iteration, compute the Zi-value from the key
authorization in the same way as the client.
Open a TLS connection to the domain name being validated on the
requested port, presenting the value
"<Zi[0:32]>.<Zi[32:64]>.acme.invalid" in the SNI field (where the
comparison is case-insensitive).
Verify that the certificate contains a subjectAltName extension
with the dNSName of “<Z[0:32]>.<Z[32:64]>.acme.invalid”, and that
no other dNSName entries of the form “*.acme.invalid” are present
in the subjectAltName extension.
So here are the gotachas and why I did my demo the way I did
The certificate that is currently being used for the domain SHOULD NOT be the one that is evaluated.
You should have a more specific binding/VHOST/serverblock which serves a certificate based on the challenge
My understanding is that if implemented properly a client should add an additional binding (like my example-challenge.acme.invalid) to the server but NOT INTERFERE with the primary domain bindings (my tls-sni.firecube.xyz )
One of the challenges I am facing is finding a client which will just give me the challenge token most of them are too clever and try to do the TLS-SNI challenge themselves
Once I crack that puzzle (currently working through it with acme.py) I will be able to give you more solid directions
I certainly haven’t got the deep understanding of the protocol that you have. My assumption was simply that the client would pass the servername in its connection request.
Anyway, the problem is solved. To get a better idea about what really happens, I used the --manual option. Surprisingly, this went through without any problem. After this I tried --apache again (“forcing”, i.e. making use of the 5 in 7 days “extra” certificates) and this time it went through as well.
Let’s see what happens in 3 months…
And thanks again! I’ll have a closer look at the protocol soon…
As mentioned I’m (obviously) not an expert on this. But I think that “only very old clients get this certificate” simply means that this certificate is returned when making a request without SNI (actually, that’s what ssllabs puts in the title of the second certificate). Requesting a connection without supplying a server name allows the server to choose one (better: use the default) which seems to be “cypht” in my case.
As the openssl connection tests show, my server returns the proper certificate when the connection is made with the servername option and the cypth-certificate when making the connection without a server name. This seems perfectly logical to me.