How to Configure Production-ready Ssl/tls in Nginx with Let’s Encrypt and Security Hardening

Learning how to configure production-ready SSL/TLS in Nginx with Let’s Encrypt and security hardening is essential for any web administrator running secure websites. This comprehensive tutorial will guide you through implementing enterprise-grade SSL/TLS encryption using free Let’s Encrypt certificates while applying critical security hardening measures. You’ll learn to set up automatic certificate renewal, implement HSTS headers, configure perfect forward secrecy, and apply additional security measures that protect your server from common attacks.

SSL/TLS encryption has become mandatory for modern websites. Search engines penalize non-HTTPS sites, and users expect secure connections. Let’s Encrypt provides free SSL certificates that are trusted by all major browsers. However, simply installing a certificate isn’t enough. Production environments require proper security hardening to prevent vulnerabilities and ensure optimal performance.

This tutorial covers everything from initial Nginx setup to advanced security configurations. You’ll implement industry best practices including cipher suite optimization, security headers, and automated monitoring. By the end, you’ll have a production-ready HTTPS setup that meets enterprise security standards.

Prerequisites and Requirements for Production-ready SSL/TLS Configuration

Before starting this tutorial on how to configure production-ready SSL/TLS in Nginx with Let’s Encrypt and security hardening, ensure you meet these requirements:

You need a Ubuntu 20.04 or newer server with root access. Your domain must point to your server’s IP address through DNS A records. Nginx should be installed and running, though we’ll cover installation steps. You’ll also need port 80 and 443 open in your firewall.

Basic Linux command-line knowledge is assumed. You should understand file editing, service management, and basic networking concepts. This tutorial takes approximately 45-60 minutes to complete, depending on your server’s performance and internet connection speed.

Your server should have at least 1GB RAM and 10GB available disk space. While Let’s Encrypt certificates work on smaller systems, production environments benefit from adequate resources for certificate management and renewal processes.

Ensure your system is updated before beginning:

sudo apt update
sudo apt upgrade -y

Step-by-Step Guide to Configure SSL/TLS in Nginx with Let’s Encrypt

Another fascinating historical case is: How to Configure Nginx as a Reverse Proxy with Ssl on Ubuntu 22.04

Step 1: Install Nginx and Certbot

First, install Nginx web server and Certbot for Let’s Encrypt certificate management:

sudo apt install nginx certbot python3-certbot-nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx

Verify Nginx is running by checking its status:

sudo systemctl status nginx

Step 2: Configure Basic Nginx Virtual Host

Create a basic configuration for your domain. Replace `example.com` with your actual domain:

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

Add this initial configuration:

server {
    listen 80;
    server_name example.com www.example.com;
    
    location / {
        return 301 https://$server_name$request_uri;
    }
    
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
}

Enable the site and test the configuration:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 3: Obtain Let’s Encrypt SSL Certificate

Use Certbot to obtain your SSL certificate. The Let’s Encrypt documentation provides additional details about certificate types and limitations:

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

Follow the prompts to provide your email address and agree to terms. Certbot will automatically modify your Nginx configuration to include SSL settings.

Step 4: Configure Production-ready SSL/TLS Settings

Replace the auto-generated SSL configuration with hardened settings. Edit your site configuration:

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

Replace the content with this production-ready configuration:

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 Configuration
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # SSL Security 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;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_session_tickets off;
    
    # HSTS and Security Headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options DENY always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    location / {
        root /var/www/html;
        index index.html index.htm;
    }
}

Step 5: Implement Additional Security Hardening

Create a separate SSL configuration file for reusability across multiple sites:

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

Add these optimized SSL parameters:

# 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;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;

# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

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

Step 6: Configure Automatic Certificate Renewal

Set up automatic renewal to prevent certificate expiration. Test the renewal process:

sudo certbot renew --dry-run

Create a renewal hook script for post-renewal actions:

sudo nano /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh

Add this script

#!/bin/bash
systemctl reload nginx

Make the script executable:

sudo chmod +x /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh

Step 7: Test and Validate SSL Configuration

Test your Nginx configuration for syntax errors:

sudo nginx -t

If successful, reload Nginx to apply changes:

sudo systemctl reload nginx

Troubleshooting Common SSL/TLS Configuration Issues

When implementing how to configure production-ready SSL/TLS in Nginx with Let’s Encrypt and security hardening, several issues commonly occur. Here are solutions for the most frequent problems:

Certificate Verification Failures: If Let’s Encrypt fails to verify your domain, ensure your DNS records point correctly to your server. Check that port 80 is accessible from the internet and not blocked by firewalls. The domain verification process requires HTTP access to `/.well-known/acme-challenge/` paths.

Mixed Content Warnings: After enabling HTTPS, you might see mixed content warnings. This happens when HTTPS pages load HTTP resources. Update all internal links, images, and scripts to use HTTPS or protocol-relative URLs. Check your application’s base URL settings.

SSL Test Failures: Use the SSL Labs SSL Test to validate your configuration. Common issues include weak cipher suites, missing security headers, or incorrect certificate chains. The configuration provided in this tutorial should achieve an A+ rating.

Performance Issues: SSL/TLS adds computational overhead. Enable HTTP/2 in your Nginx configuration to improve performance. Consider implementing SSL session caching and OCSP stapling as shown in the configuration examples above.

Similar Posts