HTTPS everywhere, with a certificate that renews itself
Look firstWhy it matters
Without HTTPS, passwords, session cookies and API secrets cross the network in the clear. An expired certificate does the opposite damage: browsers and webhook senders stop talking to the site until someone notices.
How to check
- From your computer
- On the server
- On the server
- From your computer
A good result. The first shows a 301 to https://. The second shows an expiry date in the future. The third shows a certbot renew line. The fourth lists TLS 1.2 and 1.3 and nothing older.
The setting or command
ssl_certificate and ssl_certificate_key in site_config.json, written by bench
- On the serverbench setup lets-encrypt refuses to run without it.
- On the serverThe domain must already point at the server, with port 80 open.
In a Docker install a proxy does this: Traefik (compose.https.yaml, with LETSENCRYPT_EMAIL set), nginx-proxy with acme-companion, or Caddy. The first and fourth checks still apply; renewal is the proxy's job, so read its log.
Where this comes from
- bench: bench/config/templates/nginx.confv5.31.0The nginx file bench writes allows TLS 1.2 and 1.3 only and redirects port 80 to HTTPS.
- bench: bench/config/lets_encrypt.pyv5.31.0bench setup lets-encrypt needs DNS multitenancy and adds a root cron job that runs certbot renew every day.
- bench: bench/commands/config.pyv5.31.0bench config dns_multitenant on|off exists.
- Frappe docs: Let's Encrypt SSL setupsudo -H bench setup lets-encrypt <site>; renewal by a root cron job; bench renew-lets-encrypt.
- OWASP: Transport Layer Security Cheat SheetPrefer TLS 1.3, allow 1.2 for compatibility, switch off 1.0 and 1.1, redirect HTTP to HTTPS with HSTS.
- Nmap: ssl-enum-ciphersLists the protocol versions and cipher suites a server accepts.
- frappe_docker: docs/13-explanation/04-tls-ssl-approaches.mdv4.0.1Docker installs get TLS from a proxy: Traefik, nginx-proxy with acme-companion, or Caddy.