Hello everyone,
I'm currently implementing my own ACME-based client and server for a university project, and I've generated my own root certificate to verify HTTPS requests. While attempting to send a new_account
request, I was looking for a way to pass my generated root certificate to the client in order to verify the server's certificate. However, I noticed that the verify_ssl
parameter in the ClientNetwork
class expects a boolean value.
The issue is that this parameter is only passed as an argument to the request
method of the session library, and the session documentation states that the verify
parameter can be either a boolean or a string if you want to use your own certificate chain.
Am I overlooking something, or is there a type mismatch in the constructor of the ClientNetwork
class?
Regards,
Luca
The request to the Let's Encrypt API server is validated using the cert and chain you get back from the LE server. Which, today, means your ACME Client needs to validate it trusts the ISRG Root X1
CA root. Technically, you don't have to validate that cert but you definitely should to ensure you are talking to the actual LE API server. This is the true|false option you see in that call. Setting 'false' is very poor practice.
For HTTP Challenges, the Let's Encrypt Validation servers will make HTTP requests to the server indicated by the IP in the public DNS. No cert is involved on your server unless you redirect the HTTP request to HTTPS. The LE server will follow the redirect but does not validate the cert your server showed it. It is fine to use a self-signed cert if you wish.
I say all this just to get clarity on exactly which of these "flows" you need your "generated root certificate" for. Can you explain in more detail?
Perhaps this reference is also helpful: Challenge Types - Let's Encrypt
4 Likes
Hi @lucagebhardt and welcome to the community,
firstly, there are various ACME client implementations out there. It wasn't obvious to me which one you were using at first, but based on the description, I'm presuming that you're working with certbot/acme
for the client.
Yes, this seems correct. Request supports to either turn off TLS server certificate validation completely (by setting this value to false), or to specify a collection of trusted certificates (a "bundle" in request's terminology). certbot/acme
only seems to support the simpler use case, where validation is completely skipped.
For initial development, you could just set verify_ssl
to false - you don't really need it for local client to server tests. If you do want TLS certificate validation with custom certs, note that you can also override the default CA bundle used by request externally.
4 Likes
Hey, thank you for your anwser.
I definitely want to check the certificates! But for the mentioned project, I need to implement my own ACME server and client. I generate my own root certificate, which I use to sign the certificate used by the web server implementation that handles requests such as new_account
. To validate the certificate used by the server, I need the option to pass a root certificate to my client implementation. Just to clarify, it’s for a small project in a local lab environment, and I’m referring to the Python classes in this file: certbot/acme/acme/client.py at main · certbot/certbot · GitHub.
1 Like
@Nummer378 @MikeMcQ thank you very much for your quick and helpful answers!
3 Likes
Assuming you are allowed to, it may be easier to first build a client against an ACME server like Pebble (GitHub - letsencrypt/pebble: A miniature version of Boulder, Pebble is a small RFC 8555 ACME test server not suited for a production certificate authority.), then replace the server.
Certbot uses the requests
library to communicate with acme servers - GitHub - psf/requests: A simple, yet elegant, HTTP library.
Requests uses the certifi
package - a port of the mozilla trust store - as it's trust store - GitHub - certifi/python-certifi: (Python Distribution) A carefully curated collection of Root Certificates for validating the trustworthiness of SSL certificates while verifying the identity of TLS hosts.
You can override the trust store by setting an environment variable DEFAULT_CA_BUNDLE_PATH
. See here:
https://requests.readthedocs.io/en/latest/user/advanced/
You can also have some test code that just iterates over a "fullchain" (your signed leaf, the server's intermediates and roots), ensuring the issuers match and certs were signed by one another.
I have some code that does that here:
I need to redo the new Cryptography code; it was actually easier to do in pyopenssl, but that library is essentially deprecated in favor of Cryptography.
7 Likes