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.