HTTPS with Let's Encrypt
Browsers mark a plain-http site Not secure, and anyone on the way can read or change what it sends. HTTPS fixes both — and Let's Encrypt gives the certificates for free; certbot gets them and renews them.
The café's site already runs on this server, over http (aroma.example stands in for your own domain):
curl http://aroma.example
What Let's Encrypt checks
Before it signs a certificate for aroma.example, Let's Encrypt fetches a token from http://aroma.example/.well-known/acme-challenge/… — from the internet. So:
- the domain has to point to this server —
dig +short aroma.exampleshould give this server's public address,198.51.100.24 - port 80 has to be open to the world
- nginx needs a server block with that
server_name
Get the certificate
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d aroma.example -d www.aroma.example
The first time it asks for an e-mail address (for expiry warnings) and to accept the terms. Then it edits the site's configuration itself: listen 443 ssl, the certificate files — and a redirect from http to https.
If it fails with Timeout during connect (likely firewall problem), believe it: this server's firewall only lets SSH in.
sudo ufw allow 'Nginx Full'
Nginx Full opens 80 and 443. Then run certbot again.
Check
curl -I http://aroma.example
curl https://aroma.example
sudo certbot certificates
http:// answers 301 Moved Permanently with Location: https://… — every visitor ends up on https.
Renewal
Certificates last 90 days. certbot.timer checks twice a day and renews when fewer than 30 are left. Test that renewing works:
sudo certbot renew --dry-run
systemctl list-timers certbot.timer
💡 In a script, without questions:
sudo certbot --nginx -d aroma.example --non-interactive --agree-tos -m you@example.com