# How to Secure an Nginx Web Server with Let’s Encrypt and UFW on Ubuntu
Deploying a web server using Nginx on Ubuntu is a common and efficient way to host websites and applications. However, an out-of-the-box Nginx installation transmits data in plain text and leaves the server exposed to unnecessary network traffic.
To make your web server production-ready, you must implement two critical security measures: encrypting traffic with an SSL/TLS certificate and restricting access using a firewall.
This guide provides a step-by-step workflow for securing an Nginx web server on Ubuntu Linux using Let’s Encrypt for free SSL certificates and Uncomplicated Firewall (UFW) for network security.
## Prerequisites
Before proceeding, ensure you have:
1. An Ubuntu server with Nginx installed and running.
2. A registered domain name pointing to your server’s public IP address (A record).
3. Root or `sudo` privileges on the server.
## Step 1: Configure the Uncomplicated Firewall (UFW)
UFW is a user-friendly frontend for managing iptables firewall rules on Ubuntu. Before installing SSL certificates, you must ensure your firewall is active and configured to allow only necessary traffic.
By default, UFW denies all incoming connections and allows all outgoing connections. You need to explicitly allow SSH, HTTP, and HTTPS traffic.
1. **Check UFW status:**
“`bash
sudo ufw status
“`
*It will likely say “inactive”. Do not enable it yet.*
2. **Allow SSH connections:**
This is critical. If you enable the firewall without allowing SSH, you will lock yourself out of the server.
“`bash
sudo ufw allow OpenSSH
“`
*(If you use a custom SSH port, such as 2222, use `sudo ufw allow 2222/tcp` instead).*
3. **Allow Nginx web traffic:**
Nginx registers several profiles with UFW upon installation. You can list them using `sudo ufw app list`. We will allow the `Nginx Full` profile, which opens both port 80 (HTTP) and port 443 (HTTPS).
“`bash
sudo ufw allow ‘Nginx Full’
“`
4. **Enable the firewall:**
Now that the rules are in place, enable UFW.
“`bash
sudo ufw enable
“`
*Press `y` when prompted that this may disrupt existing SSH connections.*
5. **Verify the rules:**
“`bash
sudo ufw status
“`
You should see OpenSSH and Nginx Full listed as ALLOW. Your server is now protected at the network layer.
## Step 2: Install Certbot
Certbot is the official Let’s Encrypt client used to automate the process of requesting, installing, and renewing SSL certificates.
The recommended way to install Certbot on Ubuntu is using Snap, a package manager developed by Canonical.
1. **Ensure Snapd is up to date:**
“`bash
sudo snap install core; sudo snap refresh core
“`
2. **Install the Certbot package:**
“`bash
sudo snap install –classic certbot
“`
3. **Create a symbolic link:**
This ensures the `certbot` command can be executed from anywhere in the terminal.
“`bash
sudo ln -s /snap/bin/certbot /usr/bin/certbot
“`
## Step 3: Configure the Nginx Server Block
For Certbot to automatically configure SSL for Nginx, it needs to find the correct server block in your Nginx configuration.
1. Open your Nginx configuration file for your domain (replace `yourdomain.com` with your actual domain):
“`bash
sudo nano /etc/nginx/sites-available/yourdomain.com
“`
2. Look for the `server_name` directive. It should look like this:
“`nginx
server_name yourdomain.com www.yourdomain.com;
“`
*If it says `server_name _;`, change it to your actual domain name.*
3. Save the file and exit the editor (Ctrl+X, Y, Enter in Nano).
4. Test the Nginx configuration to ensure there are no syntax errors:
“`bash
sudo nginx -t
“`
5. If the test is successful, reload Nginx to apply the changes:
“`bash
sudo systemctl reload nginx
“`
## Step 4: Obtain and Install the SSL Certificate
Now you will use Certbot to request the SSL certificate and automatically configure Nginx to use it.
1. Run the Certbot Nginx plugin:
“`bash
sudo certbot –nginx -d yourdomain.com -d www.yourdomain.com
“`
2. Certbot will guide you through the setup process:
– Enter a valid email address (used for urgent renewal and security notices).
– Agree to the Let’s Encrypt Terms of Service.
– Choose whether to share your email with the Electronic Frontier Foundation (optional).
3. Certbot will now communicate with the Let’s Encrypt servers to verify you control the domain.
Once verified, Certbot will automatically modify your Nginx configuration file to point to the new SSL certificates and configure a redirect from HTTP to HTTPS. This ensures that all visitors are forced to use the secure, encrypted version of your site.
## Step 5: Verify Certificate Auto-Renewal
Let’s Encrypt certificates are only valid for 90 days. Fortunately, the Certbot package installed via Snap automatically creates a systemd timer to renew the certificates before they expire.
You can verify the status of this timer by running:
“`bash
sudo systemctl status snap.certbot.renew.service
“`
You can also test the renewal process by running a “dry run”. This simulates the renewal process without actually modifying your certificates.
“`bash
sudo certbot renew –dry-run
“`
If the dry run reports no errors, your automatic renewals are configured correctly.
## Conclusion
By implementing UFW and installing a Let’s Encrypt SSL certificate via Certbot, you have significantly enhanced the security of your Nginx server. Network traffic is now restricted to only essential services, and all data transmitted between your server and your users is encrypted, protecting against interception and ensuring data integrity.