In today’s digital landscape, securing your website with HTTPS is no longer optional; it’s a fundamental requirement for user trust, data privacy, and even search engine optimization. This comprehensive guide will walk you through the process of securing your Nginx web server on Ubuntu 24.04 using free SSL/TLS certificates provided by Let’s Encrypt. By the end of this Tutorial, you will have a fully encrypted website, protecting data in transit and signaling to your visitors that their connection is secure.
Prerequisites for a Secure Setup
Before we dive into the steps, ensure you have the following in place:
- Ubuntu 24.04 Server: A freshly installed or existing Ubuntu 24.04 server.
- Non-root Sudo User: You should be logged in as a non-root user with
sudoprivileges. - Nginx Installed and Configured: Nginx should be installed and serving at least one domain. If not, don’t worry, we’ll cover Basic installation and configuration.
- Registered Domain Name: A domain name (e.g.,
your_domain.com) that is registered and has its A/AAAA records pointing to your server’s public IP address. This is crucial for Let’s Encrypt to verify domain ownership. - Firewall (UFW) Configured: The Uncomplicated Firewall (UFW) should be configured to allow HTTP (port 80) and HTTPS (port 443) traffic.
Step 1: Prepare Your Ubuntu Server and Nginx
First, ensure your system is up-to-date and Nginx is installed and running.
Update System Packages
Always start by updating your package lists and upgrading any existing packages to their latest versions. This helps ensure you have the most secure and stable software.
sudo apt update
sudo apt upgrade -y
Practical Tip: Performing these updates regularly is a good security practice, patching vulnerabilities and improving system stability.
Install Nginx (If Not Already Done)
If Nginx isn’t already on your server, install it now.
sudo apt install nginx -y
Once installed, Nginx should start automatically. You can verify its status:
sudo systemctl status nginx
You should see an active (running) status.
Configure UFW Firewall
If you’re using UFW, you need to allow Nginx traffic. Nginx registers profiles with UFW upon installation.
sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS'
sudo ufw allow 'OpenSSH'
sudo ufw enable
Confirm the firewall status:
sudo ufw status
You should see rules allowing traffic on ports 80 (HTTP) and 443 (HTTPS), along with SSH.
Warning: If you enable UFW and haven’t allowed SSH, you might lock yourself out of your server. Always ensure OpenSSH is allowed before enabling UFW.
Step 2: Set Up Nginx Server Block for Your Domain
Let’s Encrypt needs to verify domain ownership by connecting to your server via HTTP. This requires a properly configured Nginx server block for your domain.
Create a Root Directory for Your Website
Create a directory structure for your website’s files. Replace your_domain with your actual domain name.
sudo mkdir -p /var/www/your_domain/html
Create a Sample Index Page
Place a simple index.html file in your new root directory to test Nginx.
echo "<!DOCTYPE html><html><head><title>Welcome!</title></head><body><h1>Hello from your_domain!</h1></body></html>" | sudo tee /var/www/your_domain/html/index.html
Configure Nginx Server Block
Create a new Nginx server block configuration file for your domain:
sudo nano /etc/nginx/sites-available/your_domain
Add the following content, replacing your_domain with your actual domain name:
server {
listen 80;
listen [::]:80;
root /var/www/your_domain/html;
index index.html index.htm;
server_name your_domain www.your_domain;
location / {
try_files $uri $uri/ =404;
}
}
Save and close the file (Ctrl+X, Y, Enter).
Enable the Server Block and Test Nginx
Create a symbolic link from your sites-available file to the sites-enabled directory to enable the configuration:
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
Test your Nginx configuration for syntax errors:
sudo nginx -t
If you see syntax is ok and test is successful, restart Nginx to apply the changes:
sudo systemctl restart nginx
Now, open your web browser and navigate to http://your_domain. You should see “Hello from your_domain!”.
Pro-Tip: Double-check that your domain’s A/AAAA records are correctly pointing to your server’s public IP address. You can use tools like dig or nslookup to confirm DNS propagation.
Step 3: Install Certbot
Certbot is the official client for Let’s Encrypt, simplifying the process of obtaining and renewing SSL certificates. We’ll install the Certbot package along with its Nginx plugin.
sudo apt install certbot python3-certbot-nginx -y
This command installs Certbot and the necessary plugin that allows Certbot to automatically configure Nginx to use the new SSL certificates.
Warning: Ensure you install python3-certbot-nginx. Without it, Certbot won’t be able to automatically modify your Nginx configuration, requiring manual setup.
Step 4: Obtain Your SSL Certificate
Now, use Certbot to request and install your SSL certificate. The Nginx plugin will handle the Nginx configuration for you.
sudo certbot --nginx -d your_domain -d www.your_domain
Replace your_domain with your actual primary domain name. Include www.your_domain if you want the certificate to cover both the bare domain and its www subdomain.
Certbot will guide you through a series of prompts:
- Email Address: Enter an email address for urgent renewal notices and security warnings.
- Terms of Service: Agree to the Let’s Encrypt Terms of Service.
- Share Email: Decide if you want to share your email with the Electronic Frontier Foundation (EFF).
- Redirection: Choose whether to redirect HTTP traffic to HTTPS.
Example: When prompted for redirection, it’s generally recommended to choose option 2: Redirect. This automatically configures Nginx to force all traffic to HTTPS, improving security and SEO.
If everything is successful, Certbot will confirm that your certificate has been successfully installed and provides details about its expiry. It will also tell you where your certificate and key files are stored.
Common Mistake: If Certbot fails, check your Nginx configuration for errors (`sudo nginx -t`), ensure your domain points to the correct IP, and that port 80 is open in your firewall. Certbot needs to access your server on port 80 for the initial domain verification.
Step 5: Verify SSL Certificate Installation
After Certbot completes, it’s vital to verify that your website is indeed secured with HTTPS.
Check in Your Browser
Open your web browser and navigate to https://your_domain. You should see a padlock icon in the address bar, indicating a secure connection. Clicking on the padlock will usually show details about the certificate, including its issuer (Let’s Encrypt) and validity.
Use an Online SSL Checker
For a more thorough check, use an online SSL checker tool like SSL Labs SSL Test. Enter your domain name, and it will analyze your SSL configuration, providing a grade (A+ is ideal) and detailed information about your certificate and server setup.
Tip: If you encounter issues, such as mixed content warnings or a broken padlock, inspect your website’s console for errors. Sometimes, external resources (images, scripts) might still be loaded via HTTP.
Step 6: Configure Automatic Certificate Renewal
Let’s Encrypt certificates are valid for 90 days. To ensure continuous security, Certbot automatically sets up a cron job or systemd timer to renew your certificates before they expire.
Test the Renewal Process
You can test the automatic renewal process without actually renewing by using the --dry-run flag:
sudo certbot renew --dry-run
If this command completes without errors, your automatic renewal setup is likely working correctly. Certbot typically attempts renewal twice a day.
Warning: If the dry run fails, investigate immediately. Common reasons include changes to your Nginx configuration that prevent Certbot from validating domain ownership, or firewall rules blocking necessary ports. Certbot will send email notifications to the address you provided if renewal fails.
Next Steps for Enhanced Security
Your Nginx server is now secured with Let’s Encrypt! For an extra layer of security and to ensure browsers always connect via HTTPS, consider adding HTTP Strict Transport Security (HSTS) to your Nginx configuration. HSTS tells browsers to only interact with your server using HTTPS, even if a user explicitly types HTTP.
Edit your Nginx server block for HTTPS (the one Certbot modified, usually in /etc/nginx/sites-available/your_domain) and add the following line within the server block that listens on port 443:
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
After adding this, test your Nginx configuration and restart Nginx:
sudo nginx -t
sudo systemctl restart nginx
This setting instructs browsers to remember to use HTTPS for your domain for two years (63072000 seconds), including subdomains, and allows your domain to be preloaded into browsers’ HSTS lists. Keep your system and Nginx configurations updated regularly to maintain optimal security.
