22.9. Let's Encrypt
Table of Contents
Why Let's Encrypt Matters
When you put a backend application on the internet, you must protect traffic with HTTPS. Traditionally, HTTPS certificates were:
- Complicated to obtain.
- Expensive.
- Easy to misconfigure or forget to renew.
Let's Encrypt solves these problems by providing free, automated, and trusted TLS certificates. It has become the standard way to secure small and medium projects, side projects, and many production systems.
In this chapter you will learn what Let's Encrypt is, how it works, and how to use it with a typical Nginx or reverse proxy setup.
Key idea: Let's Encrypt gives you free, trusted TLS certificates, but you remain responsible for:
- Proving control of your domain.
- Configuring your web server correctly.
- Automating renewals and reloads.
What Let's Encrypt Is
Let's Encrypt is a Certificate Authority (CA) run by the Internet Security Research Group (ISRG). A CA is an organization that issues digital certificates that browsers trust.
Important points about Let's Encrypt:
- Free
No direct cost for certificates. - Automated
Designed to be used with tools like Certbot or built-in support in servers that implement the ACME protocol. - Trusted by browsers
Certificates are recognized by all modern browsers. - Short-lived certificates
Certificates are typically valid for 90 days. This sounds short, but it forces automation and reduces risk if a key is leaked. - Uses ACME protocol
Communication between your server and Let's Encrypt is done using ACME (Automatic Certificate Management Environment).
How Let's Encrypt Proves You Own a Domain
To get a certificate, Let's Encrypt must be sure that you control the domain that you request a certificate for.
There are several challenge types. The two most relevant for backend developers are:
HTTP-01 Challenge
The most common challenge when using web servers such as Nginx or Apache.
Workflow:
- Your ACME client (for example Certbot) contacts Let's Encrypt and says:
- "I want a certificate for
example.com." - Let's Encrypt replies:
- "Show me a special file at
http://example.com/.well-known/acme-challenge/<token>
with a specific content." - The ACME client:
- Places that file or response on your web server.
- Configures a route for
/.well-known/acme-challenge/*if needed. - Let's Encrypt makes an HTTP request to that URL.
- If it receives the expected content, it assumes:
- You control the server that responds for
example.com. - Then it issues the certificate.
Conditions for HTTP-01:
- Port 80 must reach your server.
- DNS for
example.commust correctly point to your server. - Nothing should block the
/.well-known/acme-challengepath.
DNS-01 Challenge
Used when HTTP is not possible or when you want wildcard certificates like *.example.com.
Workflow:
- ACME client asks for a certificate for
example.comor*.example.com. - Let's Encrypt says:
- "Create a TXT record in DNS for
_acme-challenge.example.comwith this token." - You or your automation:
- Create that DNS TXT record.
- Let's Encrypt checks DNS:
- If the token matches, it issues the certificate.
Conditions for DNS-01:
- You must have control over DNS for the domain.
- Often automated with DNS provider APIs.
Comparison table:
| Feature | HTTP-01 | DNS-01 |
|---|---|---|
| Used for | Single hostnames | Single hostnames and wildcards |
| Needs port 80 | Yes | No |
| Requires DNS change | No | Yes (TXT record) |
| Automation difficulty | Usually easy with web server | Harder without DNS provider API |
| Common use | Typical web apps and APIs | Multi-subdomain setups, complex routing |
The ACME Protocol in Simple Terms
ACME is the protocol that tools like Certbot use to talk to Let's Encrypt.
The general ACME flow:
- Create an account key on your server.
- Register this account with Let's Encrypt.
- Request authorization for one or more domains.
- Solve challenges (HTTP-01 or DNS-01).
- Request a certificate once challenges pass.
- Retrieve the certificate, and optionally a chain or fullchain file.
You rarely need to implement ACME yourself. Instead, you pick a client:
- Certbot
Widely used, especially with Nginx and Apache. - acme.sh
Shell based, lightweight, supports many DNS providers. - Built-in ACME support
Some reverse proxies or platforms have integrated ACME clients.
Important: Do not try to "manually download" certificates through a web UI or email when using Let's Encrypt. It is meant to be used through an ACME client and automated.
Certificates from Let's Encrypt: What You Get
A typical Let's Encrypt issuance gives you:
- A private key
For example:/etc/letsencrypt/live/example.com/privkey.pem - A certificate
cert.pemcontaining your domain certificate. - A chain certificate
chain.pemwith intermediate certificates. - A fullchain certificate
fullchain.pemwhich iscert + chaincombined.
This is usually what you give to web servers like Nginx.
Common file layout with Certbot:
| File | Description |
|---|---|
privkey.pem | Your private key, must be kept secret |
cert.pem | Domain certificate |
chain.pem | CA intermediate certificates |
fullchain.pem | cert.pem + chain.pem combined |
Never share privkey.pem. If it leaks, someone can pretend to be your site.
Using Let's Encrypt with Nginx
Most backend setups use Nginx as a reverse proxy in front of an application server.
A common minimal Nginx HTTPS configuration with Let's Encrypt looks like this:
server {
listen 80;
server_name example.com;
# Redirect all HTTP to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Important details:
- Port 80 server block usually:
- Serves challenges or redirects to HTTPS.
- Port 443 server block:
- Uses the certificate and key from Let's Encrypt.
- Certificates are PEM files.
When you configure Nginx, ensure the paths to the certificate and key match where your ACME client saves them.
Using Certbot with Nginx: A Typical Flow
On a Linux server with Nginx, a common process is:
- Install Certbot and the Nginx plugin
Exact commands depend on your Linux distribution. For example on Ubuntu:
sudo apt update
sudo apt install certbot python3-certbot-nginx- Ensure DNS points to your server
- For
example.com, set an A record to your server IP. - Verify you can reach
http://example.comfrom the internet. - Obtain and install a certificate
You can let Certbot edit Nginx configuration automatically:
sudo certbot --nginx -d example.comCertbot will:
- Ask some questions.
- Obtain the certificate with HTTP-01 challenge.
- Modify Nginx configuration to use HTTPS.
- Optionally create an HTTP to HTTPS redirect.
Or you can only obtain the certificate, and edit Nginx manually:
sudo certbot certonly --nginx -d example.com
Then you configure ssl_certificate and ssl_certificate_key in Nginx.
- Reload Nginx
After adjusting configuration:
sudo nginx -t # Test config
sudo systemctl reload nginx- Automate renewal
Certbot often sets up a cron job or systemd timer automatically.
You can test renewal with:
sudo certbot renew --dry-run
When certificates are renewed, Nginx must read the new files. Usually a reload automatically happens, or you can hook into the --deploy-hook option.
Rule: Always test a Let's Encrypt setup with a staging environment if you will try many times. Use Certbot's --staging flag to avoid rate limits during experiments.
Renewal and Short Certificate Lifetimes
Let's Encrypt certificates usually last 90 days. This is not a problem if you configure automation correctly.
With Certbot:
- Certificates are typically renewed automatically if:
- The systemd timer or cron job is installed.
- Port 80 is reachable at renewal time.
- Nginx or the web server is properly configured to allow HTTP-01 challenges.
Typical renewal command:
sudo certbot renewYou do not usually run this manually. It runs periodically and renews certificates that are near expiration.
You can add hooks, for example:
sudo certbot renew --post-hook "systemctl reload nginx"This reloads Nginx every time a certificate is renewed.
If you use DNS-01 with some ACME client, you must ensure your DNS automation still works at renewal time.
Rate Limits and Staging Environment
Let's Encrypt is a shared, public service, so it enforces rate limits. You must respect these or your domain will be temporarily blocked from obtaining certificates.
Typical rate limits (subject to change):
- Certificates per Registered Domain per week.
- Duplicate certificates per week.
To experiment safely:
- Use the staging environment:
sudo certbot --nginx -d example.com --stagingYou get test certificates that are not trusted by browsers, but you can test:
- HTTP-01 flow.
- Nginx integration.
- Automation scripts.
When you are sure everything works, remove --staging to obtain real certificates.
Important rule: When testing automation or complicated setups, always start with Let's Encrypt staging, to avoid hitting rate limits on the production servers.
Common Problems and How to Avoid Them
Port 80 Blocked or Misconfigured
Symptoms:
- Certbot errors such as:
- "Timeout during connect"
- "Connection refused"
- "Invalid response"
Causes:
- Firewall blocks port 80.
- Cloud provider security group does not allow HTTP.
- Nginx does not have a server block that listens on port 80.
- A wrong reverse proxy or container networking issue.
Solution:
- Ensure that port 80 is open in:
- Local firewall (for example UFW).
- Cloud security group (for example AWS Security Group).
- Add a basic server block for HTTP:
server {
listen 80;
server_name example.com;
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
}
Or let Certbot configure it automatically with --nginx.
Wrong DNS Configuration
Symptoms:
- Validation succeeds for some domains, fails for others.
- Certificate works for
example.combut notwww.example.com.
Cause:
- Only some hostnames point to the correct IP.
- CNAME or A records are misconfigured.
Solution:
- Check DNS records for every domain you pass to Certbot.
- Wait for DNS propagation before requesting a certificate.
Forgetting to Reload Nginx
Renewal might succeed, but Nginx will continue using the old certificate until it is reloaded.
Solution:
- Use
--post-hookor systemd to reload Nginx after renewal:
sudo certbot renew --post-hook "systemctl reload nginx"Using HTTP-01 with Multiple Load Balancers
If you have multiple reverse proxies or load balancers, HTTP-01 might fail if:
- Traffic for
/.well-known/acme-challengegoes to a different machine than the ACME client.
Solution options:
- Use DNS-01 with a DNS provider API.
- Use a dedicated "certificate manager" node or a centralized reverse proxy that terminates TLS.
- Ensure challenge paths are consistently routed.
Let's Encrypt in Containerized Setups
In Docker based environments with Nginx or Traefik as reverse proxies, Let's Encrypt is still commonly used.
Typical patterns:
- Nginx + Certbot as separate containers
- One container runs Nginx to handle web traffic.
- Another container runs Certbot to obtain and renew certificates, sharing a volume for
/etc/letsencrypt. - Traefik
- Traefik has built-in Let's Encrypt integration.
- You configure ACME in its static config.
- Traefik manages certificates automatically and stores them in a file or key-value store.
Example Nginx + Certbot volume sharing:
services:
nginx:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- certs:/etc/letsencrypt
ports:
- "80:80"
- "443:443"
certbot:
image: certbot/certbot
volumes:
- certs:/etc/letsencrypt
- ./html:/var/www/certbot
command: certonly --webroot -w /var/www/certbot -d example.com
volumes:
certs:You still must:
- Expose port 80.
- Serve the
/.well-known/acme-challengedirectory. - Reload Nginx after renewal.
Security Considerations
Using Let's Encrypt does not automatically make your site secure. It only encrypts traffic and verifies domain control.
Security notes:
- Protect private keys:
- Limit file permissions.
- Do not copy keys into version control.
- Restrict access to root or dedicated users.
- Use strong TLS configuration:
- Disable very old protocols like TLS 1.0 and 1.1.
- Prefer modern cipher suites.
- Renew certificates properly:
- Do not let certificates expire.
- Monitor expiration dates.
- Use HTTPS everywhere:
- Redirect HTTP to HTTPS.
- Set HSTS headers when you are confident of your setup.
Core rule: Let's Encrypt handles identity and encryption for your domain, but you must still handle application security, server hardening, and secret protection yourself.
Putting It All Together in a Backend Context
In a typical backend deployment with a FastAPI app and Nginx:
- Develop your app and run it with Uvicorn or Gunicorn on port 8000.
- Install Nginx as a reverse proxy and configure it to:
- Accept HTTP on port 80.
- Proxy requests to
localhost:8000. - Use Certbot / ACME client to obtain a Let's Encrypt certificate for your domain.
- Configure Nginx HTTPS server block with:
ssl_certificatepointing tofullchain.pem.ssl_certificate_keypointing toprivkey.pem.- Set up automatic renewal and Nginx reload.
- Redirect HTTP to HTTPS so all client traffic is protected.
Once configured, certificates will renew in the background. Your backend will always be served over HTTPS with a certificate that browsers trust, without any ongoing manual work.
Views: 7
KAHIBARO