Skip to main content

Implementing SSL/TLS

1. Enabling SSL

Directive Values Description
ssl on on Enables SSL for the server block
ssl_certificate /path/to/certificate.crt Path to the SSL certificate file
ssl_certificate_key /path/to/private.key Path to the private key file
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2 SSL/TLS protocols to support
ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP Allowed SSL ciphers

Example: Basic SSL Configuration

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
}

2. Configuring SSL Certificate

Directive Description Example
ssl_certificate Path to the SSL certificate file ssl_certificate /etc/ssl/certs/nginx.crt;
ssl_certificate_key Path to the private key file ssl_certificate_key /etc/ssl/private/nginx.key;
ssl_protocols SSL protocols to support (e.g., TLSv1.2, TLSv1.3) ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers Allowed SSL ciphers for the connection ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers Use server cipher preferences instead of client ssl_prefer_server_ciphers on;

Example: Basic SSL Configuration

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/nginx.crt;
    ssl_certificate_key /etc/ssl/private/nginx.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
    ssl_prefer_server_ciphers on;

    location / {
        root /var/www/html;
        index index.html;
    }
}
Note: Ensure the certificate and key files have appropriate permissions (e.g., 600) to prevent unauthorized access.

3. Setting SSL Private Key

Directive Values Description
ssl_protocols ssl, tls, tlsv1, tlsv1.1, tlsv1.2, tlsv1.3 Enables the specified SSL/TLS protocols
ssl_ciphers String of ciphers Specifies the list of SSL ciphers to use for connections
ssl_prefer_server_ciphers on, off Enables the server's cipher preferences over client's
ssl_certificate File path to certificate Path to the SSL certificate file (PEM format)
ssl_certificate_key File path to private key Path to the private key file (PEM format)

Example: Basic SSL Configuration

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/certificate.crt;
    ssl_certificate_key /path/to/private.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;
}
Note: The private key must match the certificate's public key for successful SSL handshake.
Warning: Ensure that the private key file has appropriate permissions to prevent unauthorized access.

4. Configuring SSL Protocols

Directive Values Description
ssl_protocols SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 Enables the specified SSL/TLS protocols. TLSv1.3 is supported starting from Nginx 1.25.0.
ssl_protocols SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 Disabling insecure protocols like SSLv2 and SSLv3 is highly recommended for security.

Example: Enabling TLS 1.2 and 1.3

server {
    listen 443 ssl;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
}
Note: TLSv1.3 is the most secure and efficient version of TLS, offering better performance and security than earlier versions.

5. Setting SSL Ciphers

Cipher Suite Description Security Level Notes
ssl_ciphers Defines the list of SSL/TLS ciphers that Nginx will use for connections. NEW Defaults to ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384 in newer versions.
ssl_prefer_server_ciphers When enabled, Nginx will prefer its own cipher list over the client's. Standard Set to on for better security control.

Example: Configuring SSL Ciphers

server {
    listen 443 ssl;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # Set preferred cipher suites
    ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384";

    # Prefer server cipher list
    ssl_prefer_server_ciphers on;
}
Note: Modern cipher suites like ECDHE and AES256-GCM are preferred for better security and performance.
Warning: Avoid weak ciphers like RC4, DES, or MD5. They are deprecated and pose security risks.

6. Preferring Server Ciphers

Cipher Description Security Level Notes
ECDHE-RSA-AES256-GCM-SHA384 Elliptic Curve Diffie-Hellman with RSA key exchange, AES-256 in GCM mode, SHA-384 for hashing High Recommended for strong security
ECDHE-ECDSA-AES256-GCM-SHA384 Elliptic Curve Diffie-Hellman with ECDSA key exchange, AES-256 in GCM mode, SHA-384 for hashing High Preferred when ECDSA certificates are used
ECDHE-RSA-AES128-GCM-SHA256 Elliptic Curve Diffie-Hellman with RSA key exchange, AES-128 in GCM mode, SHA-256 for hashing Medium Good balance of performance and security
ECDHE-ECDSA-AES128-GCM-SHA256 Elliptic Curve Diffie-Hellman with ECDSA key exchange, AES-128 in GCM mode, SHA-256 for hashing Medium Preferred when ECDSA certificates are used
AES256-GCM-SHA384 AES-256 in GCM mode, SHA-384 for hashing High Legacy cipher, not recommended due to lack of forward secrecy
AES128-GCM-SHA256 AES-128 in GCM mode, SHA-256 for hashing Medium Legacy cipher, not recommended due to lack of forward secrecy

Example: Setting Preferred Ciphers in Nginx

server {
    listen 443 ssl;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # Prefer strong ciphers
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
}
Note: The ssl_prefer_server_ciphers directive ensures that the server's cipher list is preferred over the client's list, allowing you to control which ciphers are used.

7. Enabling SSL Session Cache

Directive Values Description
ssl_session_cache off, none, builtin[:size], shared:name:size Configures the SSL session cache. Default is off.
ssl_session_timeout Time duration (e.g., 5m, 1h) Defines the time during which a client can reuse an SSL session. Default is 5m.

Example: Configuring SSL Session Cache

server {
    listen 443 ssl;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # Enable session cache with shared memory
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # Optional: Enable session tickets
    ssl_session_tickets on;
}
Note: The shared:SSL:10m directive creates a shared memory zone named SSL with 10MB of space for caching SSL sessions.
Warning: Session cache size should be tuned based on the expected number of concurrent connections to avoid memory exhaustion.

8. Setting Session Timeout

Directive Values Description
ssl_session_timeout 5m Configures the time during which a client can reuse a session. Default is 5m.

Example: Configuring SSL Session Timeout

server {
    listen 443 ssl;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # Set session timeout to 10 minutes
    ssl_session_timeout 10m;
}

9. Using OCSP Stapling

OCSP stapling allows the web server to provide the certificate status information directly to the client, reducing the need for clients to contact the OCSP responder.

Directive Description Default
ssl_stapling Enables OCSP stapling for SSL connections. off
ssl_stapling_verify Enables verification of the OCSP response. off
ssl_stapling_responder Specifies the OCSP responder URL to use. none

Example: Enabling OCSP Stapling

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # Enable OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # Specify the OCSP responder
    ssl_stapling_responder https://ocsp.example.com/;
}
Note: Ensure that the OCSP responder URL is accessible and that the server has proper network access to it.

10. Configuring HSTS

Directive Values Description
add_header Strict-Transport-Security Adds the HSTS header to responses
max-age 31536000 Duration in seconds the browser should remember to only use HTTPS (1 year)
includeSubDomains on Applies HSTS to all subdomains
preload on Allows the domain to be preloaded in browsers (optional)

Example: Basic HSTS Configuration

server {
    listen 443 ssl;
    server_name example.com;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

Example: HSTS with Preload

server {
    listen 443 ssl;
    server_name example.com;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
Note: HSTS is only effective over HTTPS connections. Ensure all traffic is redirected to HTTPS.
Warning: Once HSTS is enabled, browsers will enforce HTTPS for the specified duration. Misconfiguration can lead to permanent redirect issues.

11. Redirecting HTTP to HTTPS

Directive Description Example
server Defines a server block to handle HTTP requests server {
  listen 80;
  server_name example.com;
  return 301 https://$server_name$request_uri;
}
return Performs a redirect with specified status code and URL return 301 https://$server_name$request_uri;

Example: Basic HTTP to HTTPS Redirect

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    # Additional SSL configuration...
}
Note: The $server_name variable ensures the redirect preserves the original domain name, and $request_uri preserves the requested path and query parameters.

12. Using SSL with SNI

Directive Description Values Notes
server_name Defines the server name for SNI matching example.com Must match the certificate's subject alternative name (SAN)
ssl_certificate Path to the SSL certificate file /etc/ssl/certs/example.com.crt Required for SNI-enabled server blocks
ssl_certificate_key Path to the private key file /etc/ssl/private/example.com.key Must match the certificate's key
ssl_protocols SSL/TLS protocols to support tlsv1.2 tlsv1.3 Must include at least TLS v1.2 or higher
ssl_ciphers Allowed cipher suites for SSL connections ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512 Must not include weak or deprecated ciphers

Example: Basic SNI Configuration

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;

    location / {
        return 200 'Hello from example.com';
    }
}
Note: SNI allows multiple SSL certificates on the same IP address and port. Ensure that all certificates are valid and match their respective server names.
Warning: If SNI is not properly configured, clients may receive an incorrect certificate or fail to connect.

Was this article helpful?