How to Configure Production-ready Ssl/tls in Nginx with Security Hardening

How to configure production-ready SSL/TLS in Nginx with security hardening is essential for protecting your web applications and ensuring data encryption in transit. This comprehensive tutorial will guide you through implementing robust SSL/TLS configurations that meet modern security standards. You’ll learn to set up SSL certificates, configure cipher suites, enable HSTS, and implement additional security measures that protect against common vulnerabilities.

SSL/TLS security has become critical for all websites, not just e-commerce platforms. Search engines now prioritize HTTPS sites in rankings, and browsers display security warnings for non-encrypted connections. This tutorial covers advanced configurations that go beyond basic SSL setup to create a production-ready environment.

By following this guide, you’ll implement industry-standard security practices including perfect forward secrecy, OCSP stapling, and security headers. These configurations will help your server achieve high security ratings from SSL testing tools while maintaining optimal performance for your users.

Prerequisites and Requirements for SSL/TLS Configuration

Before starting this tutorial on how to configure production-ready SSL/TLS in Nginx with security hardening, ensure you have the following prerequisites in place:

You need a running Ubuntu 20.04 or 22.04 server with root or sudo access. Your server should have Nginx installed and configured with at least one website or application running. A valid domain name pointing to your server’s IP address is required for SSL certificate generation.

You’ll need an SSL certificate from a trusted Certificate Authority. This tutorial uses Let’s Encrypt certificates, which are free and automatically renewable. Alternatively, you can use commercial certificates from providers like DigiCert or Comodo.

Basic knowledge of Linux command line operations and text editors like nano or vim is assumed. You should understand fundamental Nginx configuration concepts including server blocks and location directives. Familiarity with DNS configuration and domain management will be helpful.

The estimated time to complete this tutorial is 45-60 minutes, depending on your current Nginx configuration complexity. Make sure you have access to your domain’s DNS settings if certificate validation requires DNS challenges.

Step-by-Step Guide to Configure Production-ready SSL/TLS in Nginx

Related article: How to Harden Ssh Server Security on Ubuntu Linux

Step 1: Install Certbot and obtain SSL certificates

First, install Certbot, the official Let’s Encrypt client, to obtain free SSL certificates:

sudo apt update
sudo apt install snapd
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot

Create a symbolic link to make Certbot accessible system-wide:

sudo ln -s /snap/bin/certbot /usr/bin/certbot

Obtain SSL certificates for your domain. Replace `yourdomain.com` with your actual domain:

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Step 2: Configure strong SSL/TLS settings in Nginx

Create a dedicated SSL configuration file to centralize your security settings:

sudo nano /etc/nginx/snippets/ssl-params.conf

Add the following secure SSL configuration:

# SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

Step 3: Generate strong Diffie-Hellman parameters

Generate a strong DH parameter file for perfect forward secrecy:

sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048

This process may take several minutes to complete. The 2048-bit key provides excellent security while maintaining reasonable generation time.

Step 4: Configure your site’s server block with SSL hardening

Edit your site’s Nginx configuration file:

sudo nano /etc/nginx/sites-available/yourdomain.com

Replace the existing configuration with this hardened SSL setup:

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

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

    # SSL Certificate Configuration
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # Include SSL security parameters
    include /etc/nginx/snippets/ssl-params.conf;

    # Security Headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always;

    # Your website configuration continues here
    root /var/www/yourdomain.com/html;
    index index.html index.htm index.php;

    location / {
        try_files $uri $uri/ =404;
    }
}

Step 5: Test and reload Nginx configuration

Test your Nginx configuration for syntax errors:

sudo nginx -t

If the test passes, reload Nginx to apply the new configuration:

sudo systemctl reload nginx

Step 6: Set up automatic certificate renewal

Configure automatic renewal for Let’s Encrypt certificates by testing the renewal process:

sudo certbot renew --dry-run

The renewal process is automatically configured via systemd timer. Verify the timer is active:

sudo systemctl status snap.certbot.renew.timer

Advanced Security Hardening and SSL/TLS Optimization

Step 7: Implement additional security measures

Create a comprehensive security configuration file for enhanced protection:

sudo nano /etc/nginx/snippets/security-headers.conf

Add advanced security headers:

# Advanced Security Headers
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;

# Hide Nginx version
server_tokens off;

# Prevent access to hidden files
location ~ /. {
    deny all;
    access_log off;
    log_not_found off;
}

Step 8: Configure session resumption for performance

Add session caching to improve SSL handshake performance:

sudo nano /etc/nginx/snippets/ssl-params.conf

Append these performance optimizations to your existing SSL configuration:

# SSL Session Configuration
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;

# Buffer sizes
ssl_buffer_size 8k;

Include the security headers in your server block by adding this line after the SSL parameters include:

include /etc/nginx/snippets/security-headers.conf;

Testing and Troubleshooting SSL Configuration Issues

Step 9: Verify SSL configuration with online tools

Test your SSL configuration using SSL Labs’ SSL Test tool at Qualys SSL Labs. This comprehensive test evaluates your SSL implementation and provides a security grade.

Check for common SSL issues using the command line:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com

Verify HSTS header implementation:

curl -I https://yourdomain.com

Step 10: Monitor SSL certificate expiration

Set up monitoring for certificate expiration to prevent service interruptions:

sudo certbot certificates

Check certificate validity dates:

echo | openssl s_client -servername yourdomain.com -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates

Common troubleshooting scenarios include certificate chain issues, which can be resolved by ensuring the full certificate chain is properly configured. Mixed content warnings occur when HTTPS pages load HTTP resources, requiring updates to internal links and resource references.

If you encounter “SSL handshake failed” errors, verify your cipher suite configuration supports client browsers. The official Nginx SSL module documentation provides detailed information about SSL directives and troubleshooting.

Performance issues may arise from

Similar Posts