# Configuring TLS — Nginx

Source: https://www.skillbyai.com/en/nginx/t-https

> Enable HTTPS with sensible protocols, certificates and session settings.

## Modern TLS without the guesswork

Enable HTTPS with `listen 443 ssl;`, a certificate chain in **`ssl_certificate`** (your certificate followed by intermediates) and the private key in **`ssl_certificate_key`**, readable only by root. Restrict protocols to **`TLSv1.2 TLSv1.3`**; older versions are insecure and disabled by modern browsers. For TLS 1.2, use strong cipher suites (Mozilla's SSL Configuration Generator publishes recommended "intermediate" settings); TLS 1.3 cipher suites are fixed and secure by default. Enable a **session cache** (`ssl_session_cache shared:SSL:10m;`) so returning clients resume sessions cheaply. Obtain free, automatically renewed certificates from **Let's Encrypt** with **Certbot** or another ACME client; renewals run on a timer and reload NGINX afterwards. Test your configuration with an external scanner such as SSL Labs, and monitor certificate **expiry**, because an expired certificate is a complete outage for users.

## Terminating TLS at the edge

NGINX decrypts HTTPS from clients and talks to applications on the internal network.

![A client with a padlock arrow into a proxy box holding a key icon, then plain arrows to internal application boxes inside a dashed boundary.](assets/figures/nginx/section-5-map.svg) — Figure 5.1 — TLS termination at NGINX.

## An HTTPS server with Let's Encrypt certificates

Protocols, session cache and certificate paths as created by Certbot.

```nginx
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;                                   # NGINX 1.25.1+ syntax
    server_name shop.example.com;

    ssl_certificate     /etc/letsencrypt/live/shop.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/shop.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;               # let modern clients choose
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    location / { proxy_pass http://app_backend; }
}

# obtain and install a certificate, then renew automatically:
# sudo certbot --nginx -d shop.example.com
# sudo certbot renew --dry-run
```

## Serve the full chain

Using only the leaf certificate works in some browsers (which fetch intermediates) and fails in others, especially API clients. Always configure the full chain (`fullchain.pem` with Certbot).

**Quiz:** Which TLS protocol versions should a modern NGINX configuration allow?

- [x] TLSv1.2 and TLSv1.3
- [ ] SSLv3 and TLSv1.0
- [ ] TLSv1.0 through TLSv1.3
- [ ] Only TLSv1.1

*Answer:* TLSv1.2 and TLSv1.3. TLS 1.0 and 1.1 are deprecated; 1.2 and 1.3 are the secure, supported versions.
