SSL/TLS is the foundational layer of web security, and in 2026 there is almost no excuse not to have it. Free certificate authorities, one-command automation, and built-in support in every major web server have removed every barrier. What remains is understanding the choices: which certificate type, which TLS version, which ciphers, and how to keep it all renewed.
What changed in 2026
- TLS 1.3 is now the default in all major browsers and servers. TLS 1.2 is still acceptable; TLS 1.0 and 1.1 are blocked by Chrome, Firefox, and Safari.
- Let's Encrypt issued its 5 billionth certificate — free DV certs are universal, with 90-day lifetimes and automated renewal.
- ACME protocol (RFC 8555) is stable — clients like
acme.sh, Certbot, and Caddy all speak it natively.
- Certificate Transparency logs are mandatory for all public certs; browsers reject certs not in CT logs.
- Post-quantum TLS (X25519Kyber768) is being rolled out in Chrome and Cloudflare — most servers do not need to configure it yet, but it is coming.
Certificate types explained
| Type |
Validation |
Use case |
| DV (Domain Validated) |
Proves domain ownership |
Most websites, APIs |
| OV (Org Validated) |
Proves org identity |
Company sites, adds org name to cert |
| EV (Extended Validation) |
Deep org vetting |
Legacy high-trust banking; less common now |
Wildcard (*.example.com) |
Domain + all subdomains |
Multi-subdomain setups |
| Wildcard + root |
Covers root and all subs |
SaaS products with per-customer subdomains |
For most applications, a free Let's Encrypt DV certificate is the right choice.
Get a certificate with Certbot (Nginx)
# Install Certbot
sudo apt install certbot python3-certbot-nginx -y
# Issue and install certificate
sudo certbot --nginx -d example.com -d www.example.com
# Test automatic renewal
sudo certbot renew --dry-run
Certbot installs a systemd timer that runs twice daily and renews certs with less than 30 days left. Verify with systemctl list-timers | grep certbot.
Get a certificate with acme.sh (standalone)
curl https://get.acme.sh | sh -s email=you@example.com
# HTTP-01 challenge (port 80 must be open)
~/.acme.sh/acme.sh --issue -d example.com --webroot /var/www/html
# Install to Nginx path
~/.acme.sh/acme.sh --install-cert -d example.com \
--key-file /etc/ssl/example.com.key \
--fullchain-file /etc/ssl/example.com.crt \
--reloadcmd "systemctl reload nginx"
acme.sh is useful on servers where you want more control or the Certbot package is unavailable.
Minimal Nginx TLS config (TLS 1.3 + 1.2)
server {
listen 443 ssl;
http2 on;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
# HSTS — add only after confirming HTTPS works
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 1.1.1.1 1.0.0.1 valid=300s;
}
# HTTP redirect
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
This is the Mozilla "Intermediate" configuration — compatible with all modern clients.
How to check your TLS config
| Tool |
What it checks |
ssl-checker.com or Qualys SSL Labs |
Full grade, cipher support, chain validation |
openssl s_client -connect example.com:443 |
Protocol and cert from the command line |
curl -vI https://example.com |
Certificate dates and chain |
| Mozilla SSL Config Generator |
Generates correct server configs for your version |
Aim for an A or A+ on SSL Labs for any production site.
How to pick
- Simple site or API on a single domain → Certbot
--nginx or --apache, done in one command.
- Multiple subdomains → Wildcard cert via DNS-01 challenge (
acme.sh or Certbot DNS plugin).
- Kubernetes →
cert-manager with Let's Encrypt ClusterIssuer; certificates as CRDs.
- CDN (Cloudflare, Fastly) → Use "Full (strict)" mode with an origin certificate; the CDN handles the client-facing TLS.
- Internal services → A private CA (e.g.,
step-ca) issues short-lived certs without Let's Encrypt rate limits.
Common mistakes
Not redirecting HTTP to HTTPS. Without the HTTP return 301 block, users who type http:// get a plain-text connection.
Using ssl_protocols TLSv1 or TLSv1.1. Remove these — they are cryptographically broken.
Setting HSTS before confirming HTTPS works. Once the header is sent with a long max-age, browsers enforce HTTPS and the only fix is to wait for it to expire. Test thoroughly first.
Not monitoring certificate expiry. Even with auto-renewal, monitors catch failures. Add an uptime check that alerts on cert expiry within 14 days.
Forgetting the chain file. Using only the leaf cert causes "untrusted" errors on some clients. Always use fullchain.pem.
What to skip
- Self-signed certificates on public-facing services — browsers show alarming warnings; trust is destroyed.
- Pinning TLS certificates in mobile apps unless your threat model specifically requires it; it creates brittle upgrade paths.
- TLS termination inside every microservice for internal traffic — a service mesh or mTLS with short-lived internal certs is the better pattern.
FAQ
How long do Let's Encrypt certificates last?
90 days. Certbot and acme.sh auto-renew at ~60 days; you should never notice the renewal.
Do I need to pay for a certificate?
No, for DV certificates. OV/EV certificates from commercial CAs cost money and add organization validation, but for most purposes DV is sufficient.
What is OCSP stapling?
It lets the server prove the certificate has not been revoked without the client making a separate request to the CA. Enable it for better performance and privacy.
What does "certificate chain" mean?
Your certificate is signed by an intermediate CA, which is signed by a root CA. The chain file includes both; without it some older clients cannot verify trust.
Where to go next