SSL/TLS Configuration Best Practices

From Server rental store
Jump to navigation Jump to search

This article will guide you through essential SSL/TLS configuration best practices for securing your web server. Proper SSL/TLS configuration is crucial for protecting sensitive data transmitted between your server and clients, ensuring user privacy, and building trust.

Prerequisites

Before you begin, ensure you have the following:

  • A running Linux server with a web server installed (e.g., Apache, Nginx).
  • Root or sudo privileges on the server.
  • A domain name pointing to your server's IP address.
  • An SSL/TLS certificate installed for your domain. If you don't have one, consider using Let's Encrypt for a free certificate. See Let's Encrypt Installation for more details.
  • Basic understanding of Linux command line and web server configuration.

Understanding SSL/TLS

SSL (Secure Sockets Layer) and its successor TLS (Transport Layer Security) are cryptographic protocols designed to provide secure communication over a computer network. They work by encrypting the data exchanged between a client (like a web browser) and a server. This encryption prevents eavesdropping and tampering.

Cipher Suites

Cipher suites are sets of cryptographic algorithms used to negotiate the security parameters of an SSL/TLS connection. A strong cipher suite configuration is vital for robust security. Older, weaker cipher suites should be disabled.

Recommended Cipher Suites

Modern web servers should prioritize strong, modern cipher suites. A good starting point is to use a combination of:

  • **Key Exchange:** Diffie-Hellman (DHE) or Elliptic Curve Diffie-Hellman (ECDHE)
  • **Authentication:** RSA or ECDSA
  • **Encryption:** AES (Advanced Encryption Standard) with a key size of 128 or 256 bits
  • **Hashing:** SHA-2 (SHA-256 or SHA-384)

Configuring Cipher Suites (Nginx Example)

For Nginx, you typically configure cipher suites in your server block's SSL configuration.

1. Edit your Nginx site configuration file (e.g., `/etc/nginx/sites-available/your_domain.conf`):

sudo nano /etc/nginx/sites-available/your_domain.conf

2. Add or modify the `ssl_ciphers` directive within your `server` block that handles HTTPS:

   ```nginx
   server {
       listen 443 ssl;
       server_name your_domain.com;
       ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
       ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
       # Recommended modern cipher suite configuration
       ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
       ssl_prefer_server_ciphers on;
       # ... other server configurations
   }
   ```

3. Test your Nginx configuration:

sudo nginx -t

4. Reload Nginx to apply changes:

sudo systemctl reload nginx

Configuring Cipher Suites (Apache Example)

For Apache, cipher suites are usually configured in your SSL virtual host file.

1. Edit your Apache SSL virtual host configuration file (e.g., `/etc/apache2/sites-available/your_domain-ssl.conf`):

sudo nano /etc/apache2/sites-available/your_domain-ssl.conf

2. Add or modify the `SSLCipherSuite` directive:

   ```apache
   <VirtualHost *:443>
       ServerName your_domain.com
       SSLEngine on
       SSLCertificateFile /etc/letsencrypt/live/your_domain.com/fullchain.pem
       SSLCertificateKeyFile /etc/letsencrypt/live/your_domain.com/privkey.pem
       # Recommended modern cipher suite configuration
       SSLCipherSuite 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384'
       SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
       SSLHonorCipherOrder on
       # ... other virtual host configurations
   </VirtualHost>
   ```
   Note the `SSLProtocol` directive to disable older, insecure protocols.

3. Test your Apache configuration:

sudo apachectl configtest

4. Reload Apache to apply changes:

sudo systemctl reload apache2

HTTP Strict Transport Security (HSTS)

HSTS is a security mechanism that tells web browsers to only interact with a website using secure HTTPS connections. It helps prevent "protocol downgrade attacks" and cookie hijacking.

Enabling HSTS

HSTS is enabled by sending a specific HTTP header from your web server.

1. **Nginx:** Add the `add_header Strict-Transport-Security` directive within your HTTPS `server` block:

   ```nginx
   server {
       listen 443 ssl;
       server_name your_domain.com;
       # ... other SSL configurations
       # HSTS header
       add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
       # ...
   }
   ```
   *   `max-age`: The duration in seconds for which the browser should remember to only use HTTPS. `31536000` is one year.
   *   `includeSubDomains`: (Optional) If present, the HSTS policy applies to all subdomains as well.
   *   `preload`: (Optional) Allows you to submit your domain to browser HSTS preload lists. Use with extreme caution as it's irreversible for that browser.

2. **Apache:** Add the `Header always set Strict-Transport-Security` directive within your SSL virtual host:

   ```apache
   <VirtualHost *:443>
       ServerName your_domain.com
       # ... other SSL configurations
       Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
       # ...
   </VirtualHost>
   ```
   Ensure the `mod_headers` Apache module is enabled:
sudo a2enmod headers
   Then reload Apache.

3. After applying the changes, test your configuration and reload your web server.

OCSP Stapling

OCSP (Online Certificate Status Protocol) is a method for checking the revocation status of an SSL/TLS certificate. OCSP stapling is an optimization where the web server periodically fetches the OCSP response from the Certificate Authority (CA) and "staples" it to the TLS handshake. This improves performance and privacy by offloading the OCSP check from the client to the server.

Enabling OCSP Stapling

1. **Nginx:** Add the following directives within your HTTPS `server` block:

   ```nginx
   server {
       listen 443 ssl;
       server_name your_domain.com;
       # ... other SSL configurations
       ssl_stapling on;
       ssl_stapling_verify on;
       ssl_trusted_certificate /etc/letsencrypt/live/your_domain.com/chain.pem; # Path to your intermediate certificates
       resolver 8.8.8.8 8.8.4.4 valid=300s; # Example DNS resolvers
       resolver_timeout 5s;
       # ...
   }
   ```
   *   `ssl_trusted_certificate`: This should point to your intermediate certificate chain file.
   *   `resolver`: Specifies DNS servers to use for resolving OCSP responder hostnames.

2. **Apache:** Add the following directives within your SSL virtual host:

   ```apache
   <VirtualHost *:443>
       ServerName your_domain.com
       # ... other SSL configurations
       SSLUseStapling on
       SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
       # Ensure SSLCertificateChainFile is set to your intermediate certificates
       SSLCertificateChainFile /etc/letsencrypt/live/your_domain.com/chain.pem
       # ...
   </VirtualHost>
   ```
   Ensure the `mod_socache_shmcb` and `mod_ssl` Apache modules are enabled.

3. Test your configuration and reload your web server.

Certificate Management

Keeping your SSL/TLS certificates up-to-date is critical. Expired certificates will cause security warnings in browsers and disrupt service.

Automatic Renewal

If you are using Let's Encrypt, the `certbot` tool usually sets up automatic renewal via a systemd timer or cron job.

1. To test your renewal configuration:

sudo certbot renew --dry-run
   This command simulates the renewal process without actually renewing certificates.

2. If automatic renewal is not set up or you want to ensure it's working, you can manually renew your certificates:

sudo certbot renew

Manual Renewal and Reload

If `certbot renew` completes successfully, it will automatically reload your web server. However, if you manage certificates manually or encounter issues, you might need to manually reload your web server after a successful renewal.

Testing Your Configuration

After implementing these changes, it's essential to test your SSL/TLS configuration.

1. **SSL Labs Server Test:** Visit <https://www.ssllabs.com/ssltest/> and enter your domain name. This provides a comprehensive analysis of your SSL/TLS configuration, including cipher suites, protocol support, and certificate chain. Aim for an "A+" rating.

2. **Command Line Tools:**

   *   **`openssl s_client`:** You can use `openssl` to connect to your server and inspect the certificate and cipher suite negotiated.
openssl s_client -connect your_domain.com:443 -tls1_2 -cipher ECDHE-RSA-AES256-GCM-SHA384
       (Replace `your_domain.com` and the cipher suite as needed.)

Troubleshooting

  • **"Not Secure" in Browser:** This usually indicates mixed content (HTTP resources loaded over HTTPS) or an invalid/expired certificate. Check your browser's developer console for specific errors.
  • **Cipher Suite Mismatch:** If clients cannot connect, your cipher suite configuration might be too restrictive or incompatible. Review the output of SSL Labs or `openssl s_client` for clues.
  • **HSTS Errors:** If you enabled HSTS with `preload` and need to revert, it's a complex process. Ensure you fully understand the implications before adding `preload`.
  • **OCSP Stapling Issues:** If OCSP stapling isn't working, verify your `ssl_trusted_certificate` (Nginx) or `SSLCertificateChainFile` (Apache) path, and ensure your DNS resolvers are correctly configured.
  • **Web Server Reload Failures:** Always check the web server's configuration syntax (`nginx -t` or `apachectl configtest`) before reloading. Review web server error logs (e.g., `/var/log/nginx/error.log` or `/var/log/apache2/error.log`) for detailed messages.

Further Reading