Skip to main content

SSL/TLS in Nginx: Certificates, Protocols, and Ciphers

Nginx · 29.09.2026

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.

ProtocolStatusRecommendation
TLS 1.0 / 1.1obsolete, vulnerabledisable
TLS 1.2supported everywherekeep for compatibility
TLS 1.3current standarduse 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_certificate points 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_client and curl -vI checks have been run.
← Back to Knowledge Base Ask Support