Secure Your Site: Nginx & Certbot

A Step-by-Step Guide to HTTPS with Let's Encrypt

Getting Started

This tutorial will guide you through installing Nginx (a powerful web server) and Certbot (for free SSL/TLS certificates from Let's Encrypt). We'll focus on correctly setting up Nginx for HTTP (port 80) first, which is crucial for Certbot to validate your domain and install certificates seamlessly.

Securing your website with HTTPS is essential for protecting user data, building trust, and often improving search engine rankings.

Prerequisites

Important: Ensure your domain's DNS A record (and AAAA record if using IPv6) is correctly pointing to your server's IP address before starting. DNS propagation can take some time.

Step 1: Install Nginx

First, update your server's package list and install Nginx.

sudo apt update
sudo apt install nginx

After installation, Nginx should start automatically. You can verify this (optional):

sudo systemctl status nginx

If you have a firewall enabled (like UFW), allow HTTP traffic:

sudo ufw allow 'Nginx HTTP'

Step 2: Install Certbot

Certbot is the client for Let's Encrypt. We'll install Certbot and its Nginx plugin, which automates SSL certificate configuration for Nginx.

sudo apt install python3-certbot-nginx

This command installs Certbot and the necessary plugin to integrate with Nginx.

Step 3: Initial Nginx Configuration for HTTP (Port 80)

This is a critical step. Certbot needs a working Nginx server block that correctly serves your domain over HTTP (port 80) so it can verify domain ownership using the HTTP-01 challenge.

1. Create a directory for your website's files (if it doesn't exist):

sudo mkdir -p /var/www/your_domain/html
sudo chown -R $USER:$USER /var/www/your_domain/html # Optional: for easy file management
sudo chmod -R 755 /var/www/your_domain

Replace your_domain with your actual domain name.

2. Create a basic index.html file for testing:

echo "Hello from Nginx on your_domain!" | sudo tee /var/www/your_domain/html/index.html

3. Create an Nginx server block configuration file for your domain. For example, /etc/nginx/sites-available/your_domain:

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

Paste the following configuration into the file. Replace your_domain and www.your_domain with your actual domain and its www variant.


server {
    listen 80;
    listen [::]:80; # For IPv6

    server_name your_domain www.your_domain;

    root /var/www/your_domain/html;
    index index.html index.htm;

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

    # This location block is important for Certbot's HTTP-01 challenge
    location ~ /\.well-known/acme-challenge/ {
        allow all;
        root /var/www/your_domain/html; # Or a dedicated path if you prefer
    }
}
            
Key Points for this HTTP config:
  • listen 80;: Nginx listens on port 80 for incoming HTTP requests.
  • server_name your_domain www.your_domain;: Specifies the domain(s) this block serves. Certbot uses this.
  • root /var/www/your_domain/html;: The directory where your website files are stored.
  • The location ~ /\.well-known/acme-challenge/ block ensures Certbot can place temporary files for domain validation. Some Certbot Nginx plugin versions might not strictly need this if they modify the config directly, but it's good practice.
  • No SSL settings (like listen 443 ssl; or ssl_certificate) are included at this stage. Certbot will add these later.

4. Enable this server block by creating a symbolic link to the sites-enabled directory:

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

It's a good idea to remove or disable the default Nginx server block if you haven't already, to avoid conflicts:

sudo rm /etc/nginx/sites-enabled/default # If it exists and you don't need it

Step 4: Test Nginx Configuration

Before proceeding, always test your Nginx configuration for syntax errors:

sudo nginx -t

If the test is successful, you'll see output like:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If there are errors, the output will indicate the file and line number causing the issue. Fix them and re-test.

Once the test is successful, reload Nginx to apply the changes:

sudo systemctl reload nginx

At this point, you should be able to access your website via HTTP (e.g., http://your_domain) and see your "Hello from Nginx..." message. This confirms Nginx is correctly serving your site on port 80.

Step 5: Obtain and Install SSL Certificate with Certbot

Now that Nginx is correctly configured for HTTP, you can run Certbot to obtain and install SSL certificates.

sudo certbot --nginx

Certbot will guide you through the process:

If successful, Certbot will configure Nginx to use the SSL certificate and set up HTTPS. It typically also asks if you want to redirect HTTP traffic to HTTPS (recommended).

Certbot automatically modifies your Nginx server block file (e.g., /etc/nginx/sites-available/your_domain) to include SSL settings (listen 443 ssl;, ssl_certificate, ssl_certificate_key, etc.) and potentially a redirect from HTTP to HTTPS.

Step 6: Verify SSL and Auto-Renewal

1. Verify SSL: Open your website in a browser using https://your_domain. You should see a padlock icon indicating a secure connection. You can also use online tools like SSL Labs SSL Test (https://www.ssllabs.com/ssltest/) to check your SSL configuration.

2. Automatic Renewal: Let's Encrypt certificates are valid for 90 days. The Certbot package you installed should automatically set up a cron job or systemd timer to renew your certificates before they expire. You can test the renewal process (without actually renewing if it's not due yet) with:

sudo certbot renew --dry-run

If this command runs without errors, your auto-renewal is likely set up correctly.

References & Further Reading

For more in-depth information, you can refer to these excellent resources:

Congratulations! You've successfully set up Nginx with SSL/TLS using Certbot.

Keep your server updated and monitor your renewal process.