Skip to main content

Implementing Advanced SSL

1. Configuring Client Certificates

Directive Description Values
ssl_client_certificate Path to the CA certificate file used to verify client certificates /etc/ssl/certs/ca.crt
ssl_verify_client Enables or disables client certificate verification on, off, optional, optional_no_ca
ssl_verify_depth Maximum depth of the certificate chain to verify 1, 2, 3
ssl_client_certificate Path to the CA certificate file used to verify client certificates /etc/ssl/certs/ca.crt

Example: Basic Client Certificate Configuration

server {
    listen 443 ssl;
    ssl_certificate /etc/ssl/certs/server.crt;
    ssl_certificate_key /etc/ssl/private/server.key;

    # Enable client certificate verification
    ssl_verify_client on;
    ssl_verify_depth 2;
    ssl_client_certificate /etc/ssl/certs/ca.crt;

    location / {
        # Your application logic here
    }
}
Note: When ssl_verify_client is set to on, the client must present a valid certificate or the request will be rejected.

2. Verifying Client Certificates

Directive Values Description
ssl_verify_client on, off, optional Enables or disables client certificate verification. optional allows connection without a certificate but still verifies if one is provided.
ssl_verify_depth 1-9 Sets the maximum depth of the certificate chain to verify. Default is 1.
ssl_client_certificate File path Path to the CA certificate file used to verify client certificates.
ssl_trusted_certificate File path Path to the CA certificate file containing trusted CAs for client verification.

Example: Enabling Client Certificate Verification

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

    # Enable client certificate verification
    ssl_verify_client on;
    ssl_verify_depth 2;
    ssl_client_certificate /path/to/ca.crt;
    ssl_trusted_certificate /path/to/trusted-ca.crt;

    location / {
        # Access to client certificate info via variables
        return 200 "Client CN: $ssl_client_s_dn";
    }
}
Note: The ssl_client_s_dn variable contains the subject distinguished name of the client certificate, if available.
Variable Description Availability
$ssl_client_s_dn Subject Distinguished Name of the client certificate Available when ssl_verify_client is enabled
$ssl_client_i_dn Issuer Distinguished Name of the client certificate Available when ssl_verify_client is enabled
$ssl_client_serial Serial number of the client certificate Available when ssl_verify_client is enabled
$ssl_client_verify Result of client certificate verification (SUCCESS, FAILED, or NONE) Available when ssl_verify_client is enabled
Warning: When ssl_verify_client is set to optional, the server still verifies any client certificate provided, but does not require one. This is useful for mutual TLS where some clients may not have certificates.

3. Extracting Client Certificate Info

Directive Description Values
ssl_verify_client Enables client certificate verification on, off, optional
ssl_verify_depth Maximum depth of certificate chain to verify 1 to 10
ssl_client_certificate Path to CA certificate file for verification File path

Example: Configuring Client Certificate Verification

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

    ssl_verify_client on;
    ssl_verify_depth 2;
    ssl_client_certificate /path/to/ca.crt;

    location / {
        # Access client certificate info via variables
        return 200 "Client CN: $ssl_client_s_dn_cn\n";
    }
}
Note: The $ssl_client_s_dn_cn variable contains the subject's common name from the client certificate.
Variable Description Example Value
$ssl_client_s_dn_cn Subject's Common Name john.doe@example.com
$ssl_client_s_dn Full Subject Distinguished Name /CN=john.doe@example.com/O=Example Inc./C=US
$ssl_client_i_dn_cn Issuer's Common Name ca.example.com
$ssl_client_serial Client certificate serial number 0x123456789ABCDEF
$ssl_client_fingerprint SHA-1 fingerprint of client cert AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD

4. Using Certificate Chain

Directive Description Example
ssl_certificate Specifies the certificate file for the server ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key Specifies the private key file for the server ssl_certificate_key /path/to/private.key;

Example: Configuring SSL with Certificate Chain

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/fullchain.pem;
    ssl_certificate_key /etc/ssl/private/private.key;

    # Optional: Set DH parameters for forward secrecy
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

    # Optional: Enable HSTS
    add_header Strict-Transport-Security "max-age=31536000";
}
Note: The fullchain.pem file should contain both the server certificate and any intermediate certificates in the correct order.

5. Implementing OCSP Must-Staple

Directive Description Values Notes
ssl_stapling Enables OCSP stapling for SSL certificates on | off Must be enabled to use OCSP must-staple
ssl_stapling_verify Enables verification of the OCSP response on | off Recommended for security
ssl_trusted_certificate Specifies the file containing trusted CA certificates File path Required for stapling verification

Example: Basic OCSP Stapling Configuration

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;

    # Path to trusted CA certificates
    ssl_trusted_certificate /path/to/trusted-ca.pem;
}
Note: OCSP stapling reduces the need for clients to contact the CA directly, improving performance and privacy.

6. Configuring SSL Session Tickets

Directive Values Description
ssl_session_tickets on | off Enables or disables the use of SSL session tickets for session resumption. Default is on.
ssl_session_timeout Time duration (e.g., 5m, 1h) Sets the time during which a client can reuse the session. Default is 5m.

Example: Enabling SSL Session Tickets

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

    ssl_session_tickets on;
    ssl_session_timeout 10m;
}
Note: Session tickets are more secure than session IDs as they do not require server-side storage. They are ideal for load-balanced setups.

7. Using ECDH Curves

Curve Description Security Level Notes
secp256r1 Prime field curve (also known as P-256) High Recommended for most use cases
secp384r1 Prime field curve (also known as P-384) Very High Stronger security, higher resource usage
secp521r1 Prime field curve (also known as P-521) Ultra High Most secure, but slower performance
brainpoolP256r1 Brainpool curve, alternative to NIST curves High Compliant with EU standards
brainpoolP384r1 Brainpool curve, alternative to NIST curves Very High Compliant with EU standards
x25519 Curve25519 (Elliptic Curve Diffie-Hellman) High Fast and secure, preferred for forward secrecy
x448 Curve448 (Elliptic Curve Diffie-Hellman) Very High High performance, suitable for high-security environments

Example: Configuring ECDH Curves in Nginx

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

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

    # Enable ECDH with specific curves
    ssl_ecdh_curve secp256r1 secp384r1 x25519;

    # Prefer ECDH over RSA for key exchange
    ssl_prefer_server_ciphers on;

    # Additional security settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
}
Note: The ssl_ecdh_curve directive specifies the curves to use for ECDH key exchange. It is recommended to include at least one modern curve like x25519 for optimal performance and security.
Warning: Older curves like secp256r1 and secp384r1 are still widely supported but may be phased out in the future. Ensure that your clients support the selected curves.

8. Implementing Certificate Pinning

Certificate pinning is a security technique that ensures a client (e.g., browser or application) only accepts a specific certificate or set of certificates from a server, rather than accepting any valid certificate in the trust chain. This helps prevent man-in-the-middle (MITM) attacks by ensuring that only known certificates are accepted.

Directive Description Values Notes
ssl_verify_certificate Enables or disables certificate verification on, off Default: on. When enabled, Nginx verifies the certificate chain.
ssl_verify_depth Controls how many certificates in the chain are verified number Default: 1. Set to a higher value for longer chains.
ssl_trusted_certificate Specifies the file containing trusted CA certificates path/to/trusted/certs.pem Used for verifying server certificates.
ssl_stapling Enables OCSP stapling to reduce server load and improve security on, off Default: off. Requires ssl_stapling_resolver.
ssl_stapling_resolver Defines the DNS resolver used for OCSP requests ip address, ip address port Example: 8.8.8.8.

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;
    ssl_trusted_certificate /path/to/trusted-certs.pem;

    # Enable OCSP stapling
    ssl_stapling on;
    ssl_stapling_resolver 8.8.8.8;

    # Verify certificate chain
    ssl_verify_certificate on;
    ssl_verify_depth 2;
}
Note: OCSP stapling allows the server to provide the certificate status (via an OCSP response) to clients, reducing the need for clients to query the CA directly.
Warning: If ssl_verify_certificate is disabled, the server will not validate the certificate chain, which can lead to security vulnerabilities.

9. Configuring Early Data

Directive Values Description
ssl_early_data on | off Enables or disables support for TLS 1.3 early data. NEW in Nginx 1.25.0

Example: Enabling Early Data

server {
    listen 443 ssl http2;
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_early_data on;
}
Note: Early data support requires Nginx 1.25.0 or later and OpenSSL 3.0.0 or later.

10. Implementing Encrypted Client Hello

Directive Description Values Notes
ssl_early_data Enables support for TLS 1.3 early data on | off Requires Nginx 1.25.0+; enables encrypted client hello (ECH) support
ssl_ech_config Specifies the ECH configuration to use base64 string or file path Must be set to enable ECH; format defined by RFC 8446
ssl_ech_required Enforces ECH usage for all connections on | off Requires ECH to be used; otherwise, connection fails

Example: Enabling ECH in Nginx

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

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

    # Enable ECH support
    ssl_early_data on;
    ssl_ech_config "...base64-encoded-config...";
    ssl_ech_required on;
}
Note: ECH is a feature of TLS 1.3 and requires support from both client and server.

11. Using Multiple SSL Certificates

Directive Description Example
ssl_certificate Specifies the certificate file for the server ssl_certificate /path/to/cert.pem;
ssl_certificate_key Specifies the private key file for the server ssl_certificate_key /path/to/key.pem;
ssl_trusted_certificate Specifies the certificate file for verifying client certificates ssl_trusted_certificate /path/to/trusted.pem;

Example: Configuring Multiple Certificates

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;

    # Additional certificate for subdomain
    ssl_certificate /etc/ssl/certs/sub.example.com.crt;
    ssl_certificate_key /etc/ssl/private/sub.example.com.key;

    # Optional: Trusted CA certificate
    ssl_trusted_certificate /etc/ssl/certs/ca.crt;
}
Note: When using multiple certificates, ensure that the certificate files are correctly referenced and accessible by the Nginx process.

12. Monitoring SSL Certificate Expiry

Property Description Example
ssl_certificate Path to the SSL certificate file /etc/ssl/certs/nginx.crt
ssl_certificate_key Path to the private key file /etc/ssl/private/nginx.key
ssl_stapling Enables OCSP stapling for improved performance on
ssl_stapling_verify Enables verification of OCSP responses on

Example: Setting up SSL with OCSP Stapling

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/nginx.crt;
    ssl_certificate_key /etc/ssl/private/nginx.key;

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
}
Note: OCSP stapling reduces the burden on the client by allowing the server to provide the certificate status directly.

Monitoring Certificate Expiry

  • Use openssl x509 -in /path/to/cert.crt -noout -dates to check expiry date
  • Set up automated alerts using cron jobs or monitoring tools like Nagios, Zabbix, or Prometheus
  • Configure ssl_stapling to improve performance and security

Was this article helpful?