Securing your Nginx server with a free SSL certificate from Let's Encrypt is a great step to ensure your website traffic is encrypted and secure. We will use Certbot, the officially recommended tool by the Electronic Frontier Foundation (EFF), to automate the issuance and installation process.
Here is a complete step-by-step guide. This guide assumes you are using Ubuntu or Debian, which are the most common distributions for this setup.
Prerequisites
Before you begin, ensure you have:
- An Nginx server installed and running.
- A registered domain name (e.g., example.com).
- DNS Records configured: Your domain's A record must point to your server's public IP address.
- Root or sudo access to your server.
Step 1: Configure the Nginx Server Block
Certbot is smart enough to find your Nginx configuration and automatically inject the SSL settings, but only if your server_name directive is set correctly.
-
Open your Nginx configuration file for your site. Depending on your OS, this is typically located in
/etc/nginx/sites-available/example.comor/etc/nginx/conf.d/example.com.conf. -
Ensure the
server_nameexplicitly lists the domains you want certificates for.
Here is a minimal example of what that server block should look like before Certbot touches it:
server {
listen 80;
listen [::]:80;
# Certbot looks for this line to know which file to update
server_name example.com www.example.com;
root /var/www/yourdomain.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
- After verifying or making any changes, always test your Nginx config for syntax errors:
sudo nginx -t
- If the test is successful, reload Nginx to apply the changes:
sudo systemctl reload nginx
Step 2: Install Certbot
I will walk you through the official installation method recommended by the Electronic Frontier Foundation (the creators of Let's Encrypt).
They recommend using Snap to install Certbot. This method ensures you always have the latest, most secure version of Certbot, and it works universally across almost all modern Linux distributions (Ubuntu, Debian, etc.).
- Ensure Snap is Installed and Updated :
sudo snap install core
sudo snap refresh core
- Remove Old Versions of Certbot (If Applicable)
If you previously tried to install or had an older version of Certbot, you should remove it before going any further to prevent conflicts.
sudo apt-get remove certbot
- Now, install the Certbot package itself using Snap. The
--classicflag is required because Certbot needs broader system access to read and modify your Nginx configuration files.
sudo snap install --classic certbot
- Next, create a symbolic link so you can easily run the certbot command from anywhere in your terminal:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Step 3: Allow HTTPS Through the Firewall
If you have the Uncomplicated Firewall (ufw) enabled, you need to allow HTTPS traffic.
Check the current status:
sudo ufw status
It will probably look like this, meaning that only HTTP traffic is allowed to the web server :
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)
Allow Nginx Full (which covers both HTTP on port 80 and HTTPS on port 443) and delete the redundant Nginx HTTP profile allowance :
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
Your status should now look like this :
sudo ufw status
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx Full (v6) ALLOW Anywhere (v6)
Step 4: Obtain and Install the SSL Certificate
Now, run certbot with the --nginx plugin. This will automatically obtain the certificate and modify your Nginx configuration to serve it.
Run the following command, using -d to specify the domain names we’d like the certificate to be valid for, replacing those domain names with your own:
sudo certbot --nginx -d example.com -d www.example.com
During the setup, Certbot will ask you a few questions:
- Enter an email address (used for urgent renewal and security notices).
- Agree to the Terms of Service.
- Choose whether or not you want to share your email with the Electronic Frontier Foundation (EFF).
After going through the above process, you should see a message confirming that it was successful. This message will also indicate where your certificates are stored:
OutputIMPORTANT NOTES:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem
This certificate expires on 2022-06-01.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
Once completed, Certbot will download the certificate, apply it to your Nginx configuration, and automatically set up redirects so all HTTP traffic is forced to HTTPS. You can now visit https://example.com (replace with your own domain) in your browser and notice your browser’s security indicator. It should indicate that the site is properly secured, usually with the secure padlock icon.
Step 5: Verify Certificate Auto-Renewal
Let's Encrypt certificates are only valid for 90 days. Fortunately, the Certbot snap package automatically creates a systemd timer that runs twice a day to renew any certificate within 30 days of expiration.
You can check the status of this background timer with :
sudo systemctl status snap.certbot.renew.service
and see the output :
Output○ snap.certbot.renew.service - Service for snap application certbot.renew
Loaded: loaded (/etc/systemd/system/snap.certbot.renew.service; static)
Active: inactive (dead)
TriggeredBy: ● snap.certbot.renew.timer
To guarantee that the automated renewal process will work when the time comes, you can safely simulate a renewal by running a dry run:
sudo certbot renew --dry-run
If you see no errors, you are all set! Certbot will handle the updates and seamlessly reload Nginx in the background before your certificates expire.