Updated Answer:
I'm marking @SteffenUllich 's answer as the correct one, but I'll just expand on parts of it in relation to what's inside the bundles and the Trust Store he references in his answer.
Files Let's Encrypt Gives You:
The error appeared to indicate that I had a broken Chain of Trust and was missing at least one cert. But I couldn't know what I was missing until I understood what certs that I had.
So I reviewed the files Let's Encrypt gave me which live in the path /etc/letsencrypt/live/example.com/
and found the bundles were comprised of:
cert.pem: The server's cert
chain.pem: Let's Encrypt's "R3" cert + "ISRG Root X1" ("Intermediate Cert")
fullchain.pem: "chain.pem" + "cert.pem"
privkey.pem: Your Private key. The Public key is encoded into cert.pem
NOTE: To validate the above using a one-liner, replace mail.example.com
with your own cert name in the path:
while openssl x509 -noout -text; do :; done < /etc/letsencrypt/live/mail.example.com/cert.pem
while openssl x509 -noout -text; do :; done < /etc/letsencrypt/live/mail.example.com/chain.pem
while openssl x509 -noout -text; do :; done < /etc/letsencrypt/live/mail.example.com/fullchain.pem
Trust Store:
It appeared that my initial attempt to validate the server cert lacked a "Trust Anchor" enabling the chain to be traced back to the origin.
HOWEVER: If the -CAfile
is not specified, as Steffen notes openssl
will parse the "Trust Store" to find a root cert to complete the Chain of Trust.
To install a "Trust Store", search for package "ca-certificates" / "ca-certificates-bundle" in your distro.
So since the CA certs are already there, nothing additional need be downloaded for the chain to be traced successfully as I erroneously stated in my original answer. Indeed, the verification is more likely to succeed if you leave openssl
to just parse everything in the Trust Store until it finds something that matches.
To find the location of your "Trust Store":
openssl version -d
In Alpine Linux, this is /etc/ssl
Conclusion:
Thanks to Steffen for bringing to my attention that the command I issued succeeded for the wrong reason ;-). And openssl
documentation could be a bit better to be fair...