What Nginx needs to serve traffic over HTTPS
To accept HTTPS connections, a server block needs three things: a certificate, a private key, and the ssl_protocols directive, which limits the list of allowed TLS versions. The certificate confirms that the domain belongs to the server owner, the key decrypts the traffic, and the protocol version determines which browsers and bots can connect at all.
A free certificate from Let's Encrypt via certbot covers most cases and renews automatically through cron. How to issue and attach such a certificate in practice is described in the article on SSL in Nginx via certbot. Here we cover the server configuration itself: which directives are mandatory and why the cipher suite matters more than it looks.
A basic server block for HTTPS
A minimal working configuration with the certificate already on disk looks like this.
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_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers off;
root /var/www/example.com;
index index.html;
}
fullchain.pem must include the certificate authority's intermediate certificate, otherwise some browsers and every console client such as curl will complain about an incomplete chain, even though a regular browser will still open the page thanks to a chain cache.
Redirecting HTTP to HTTPS without loops
After enabling HTTPS, the old port 80 needs to become a redirect instead of continuing to serve the same content.
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
A common mistake is placing the redirect inside the same block where listen 443 ssl is already enabled: then trying to open the site over HTTP gives the browser a TLS error before return can fire. General rules for the rewrite and return directives are covered in the article on redirects in Nginx.
Protocols and cipher suites: what to choose in 2026
TLS 1.0 and TLS 1.1 are officially obsolete and disabled in modern browsers — keeping them enabled brings no compatibility benefit but leaves a vulnerable surface.
| Protocol | Status | Recommendation |
|---|---|---|
| TLS 1.0 / 1.1 | obsolete, vulnerable | disable |
| TLS 1.2 | supported everywhere | keep for compatibility |
| TLS 1.3 | current standard | use as the primary protocol |
For TLS 1.3 the cipher suite is set separately through ssl_conf_command Ciphersuites, since the old ssl_ciphers directive does not affect it. On a ZevsHost.net VDS with a modern OpenSSL, the line ssl_ciphers HIGH:!aNULL:!MD5; is enough for TLS 1.2 — it cuts off unencrypted and outdated algorithms without touching fast modern ciphers.
Checking the setup: what to look at after deployment
After editing the config, make sure the certificate is served correctly and without chain errors.
nginx -t— syntax check of the config before reloading.openssl s_client -connect example.com:443 -servername example.com— which certificate and protocol were actually negotiated.curl -vI https://example.com/— response code and headers with no certificate warnings.- Checking the certificate expiry date:
openssl x509 -enddate -noout -in fullchain.pem.
Summary: SSL/TLS checklist for Nginx
- Only TLSv1.2 and TLSv1.3 are left in
ssl_protocols. ssl_certificatepoints to the fullchain, not just the domain certificate.- Port 80 serves a 301 redirect to https instead of duplicating content.
- Automatic renewal has been tested with
certbot renew --dry-run. - After deployment,
openssl s_clientandcurl -vIchecks have been run.