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.