As you may already know, Certbot is a free, open-source software tool designed to automatically obtain and install SSL/TLS certificates for websites. It is developed by the Electronic Frontier Foundation (EFF) and serves as the primary client for Let’s Encrypt, a free certificate authority.
You can install certbot using your OS package manager (apt/yum). After that, if you already have an Apache Webserver running on http://<yourdomain>, then you can just run ‘sudo certbot –apache‘ which will use Certbot Apache plugin to detect the configuration and domain, then it generates/installs the SSL key/certificate, and automatically will modify web server configurations to use the new certificate. The first time you run it, you will be asked for an email address and prompted to agree to terms of service; it will also ask by prompting you to confirm the domain for which you are generating the certificate, finally it will ask if you want automatically redirect all HTTP traffic to HTTPS on your web server configuration. The certificate will be valid for 90 days, and to renew it you will have to run ‘sudo certbot renew‘.
Below you have more details about what internally happens when you run the command certbot.
1. Request: Certbot sends a request for a certificate for your domain to Let's Encrypt (https://acme-v02.api.letsencrypt.org)
2. Challenge Issuance: The Let's Encrypt server responds by issuing a challenge that includes a unique, short-lived random token.
3. Validation (2 possible methods):
- HTTP-01: Certbot places the token in a specific file on your web server to serve to HTTP request /.well-known/acme-challenge/<TOKEN>.
- DNS-01: Certbot uses the token to create (for) a specific DNS TXT record at _acme-challenge.<YOUR_DOMAIN>.
4. Verification: Let’s Encrypt’s servers then verify that the token is correctly placed to prove you control the domain.
5. CSR Generation & Submission: Only after the challenges are successfully validated, Certbot generates the private key and the CSR, which it then submits to the CA to finalize the issuance.
6. Certbot installs the private key, the signed certificate for your domain, and CA certificate in the directory '/etc/letsencrypt/live/<yourdomain>/'.
In case you have HAProxy as frontend, to install a Let’s Encrypt certificate you can create the following frontend and backend configurations on the ‘haproxy.cfg’ file. This configuration will forward any incoming request like ‘/.well-known/acme-challenge/‘ to 127.0.0.1:8888 (assuming that we don’t have anything running on port 8888).
root@vps-2153e875:~# vi /etc/haproxy/haproxy.cfg
---
frontend all
bind *:80
...
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
...
---
backend letsencrypt-backend
server letsencrypt 127.0.0.1:8888
---
After that, we run the certbot command with the options indicated below. The combination of –standalone and –http-01-port=8888 will run its own temporary web server on port 8888 to handle the domain validation challenge. Although we indicated port 8888, Let’s Encrypt will do the domain validation by accessing http port 80 of our domain, which will arrive to HAProxy, and then it will internally forward the request to port 8888. The ‘-d‘ option is to indicate our domain.
root@vps-2153e875:~# certbot certonly --standalone -d adib.express --non-interactive --agree-tos --email XXX@YYY.com --http-01-port=8888
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for adib.express
---
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/adib.express/fullchain.pem
Key is saved at: /etc/letsencrypt/live/adib.express/privkey.pem
This certificate expires on 2026-03-19.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
---
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
After running the previous command, we will have the key/certificate in the location indicated below. ‘cert.pem‘ is our domain certificate, ‘chain.pem‘ is the CA intermediate certificate, ‘fullchain.pem‘ is the concatenation of our domain certificate and the CA certificate, and ‘privkey.pem‘ is the private key associated to our domain certificate.
root@vps-2153e875:~# ls -l /etc/letsencrypt/live/adib.express/
total 8
-rw-r--r-- 1 root root 692 Dec 19 18:18 README
lrwxrwxrwx 1 root root 36 Dec 19 18:18 cert.pem -> ../../archive/adib.express/cert1.pem
lrwxrwxrwx 1 root root 37 Dec 19 18:18 chain.pem -> ../../archive/adib.express/chain1.pem
lrwxrwxrwx 1 root root 41 Dec 19 18:18 fullchain.pem -> ../../archive/adib.express/fullchain1.pem
lrwxrwxrwx 1 root root 39 Dec 19 18:18 privkey.pem -> ../../archive/adib.express/privkey1.pem
To conclude and set the certificate/key for HAProxy, we concatenate the ‘fullchain.pem‘ file with the ‘privkey.pem‘ file, in one new single file (e.g. ‘adib.express.pem‘), and we reference it in the HAProxy configuration file.
frontend all
mode http
bind :80
bind :443 ssl crt /etc/letsencrypt/live/adib.express/adib.express.pem
...
Now we can access from our browser to https://<domain>, and check that we are not getting any errors, and verify the certificate expiration date from the browser’s padlock/tune icon. Of course, we can also check the certificate details and expiration date using the ‘openssl x509 -text -in cert.pem‘ command.
Adib Ahmed Akhtar