Running a HTTPS website with Let's encrypt (for free)

A colorful RGB key board with a secured USB token

Intro

Yes, you may have your website running HTTPS without having to pay for a SSL/TLS certificate.

Prerequisites

But first you need a working domain name, pointing to your web server. In other words, it is required to have your site running at http://your-domain-name.com first. For now, just http.

Using free certificate with ACME certbot

There are some different ways that will enable you to use Let’s Encrypt free certificates. And in this post, i will guide you to use certbot to both retrieve a SSL certificate and also renew it automatically before it gets expired.

Step 1: Go to Certbot website

Cert bot website

Step 2: Select software configuration

My server configuration is nginx running on a RockyLinux server. So, the selection should be

  • nginx as the software
  • Linux (pip) as the platform. I want to use python pip as the package manager to install other tools.

Step 3: Install dependencies

With that selection being in place, certbot website guides me to install some dependencies before i can actually have certbot running

Certbot - install dependencies

So, i just go ahead and run

sudo dnf install python3 python-devel augeas-devel gcc

Step 4: Remove old certbot package (if there is any)

sudo dnf remove certbot

Step 5: Setup python virtual environment

sudo python3 -m venv /opt/certbot/
sudo /opt/certbot/bin/pip install --upgrade pip

Step 6: Install certbot using pip

sudo /opt/certbot/bin/pip install certbot certbot-nginx

So that it will be available whenever you type certbot in your command prompt

sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot

Step 8: Obtaining first certificate

I want cerbot to obtain the certificate and edit nginx configuration automatically, so I will issue this command:
sudo certbot --nginx

certbot is going to repond with a messsage:
Saving debug log to /var/log/letsencrypt/letsencrypt.log

And if you run certbot for the first time on the machine, it will ask you for an email, in case they need to contact you.

Enter email address or hit Enter to skip.
(Enter 'c' to cancel): just-enter-your-email@gmail.com

And then it will ask you to read and agree with the terms of service:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at:
https://letsencrypt.org/documents/LE-SA-v1.5-February-24-2025.pdf
You must agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y <-- Yes, of course

An other interactive question:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: <-- y or n, you decide
Account registered.
Please enter the domain name(s) you would like on your certificate (comma and/or
space separated) (Enter 'c' to cancel):

At this step, it is expected that there already is a server configuration in your nginx config, something that should be similar to this:

server {
listen 80;
server_name your-domain-name.com;

root /usr/share/nginx/html;
index index.html;
# Other configuration ...
}

And you now should enter your domain name in answer.

Requesting a certificate for your-domain-name.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your-domain-name.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your-domain-name.com/privkey.pem
This certificate expires on 2025-09-26.
These files will be updated when the certificate renews.

Deploying certificate
Successfully deployed certificate for your-domain-name.com to /etc/nginx/conf.d/00default.conf
Congratulations! You have successfully enabled HTTPS on https://your-domain-name.com

Now, you may verify the result of certbot action by reviewing nginx configuration file.
You may notice that certbot has automatically added a redirect configuration if there is a request to you site using http:

server {
if ($host = your-domain-name.com) {
return 301 https://$host$request_uri;
} # managed by Certbot


listen 80 ;
server_name your-domain-name.com;
return 404; # managed by Certbot
}

And it also add a server block to handle https traffic:

server {

root /usr/share/nginx/html;
index index.html;


server_name your-domain-name.com; # managed by Certbot

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/your-domain-name.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/your-domain-name.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

Congratulations!
Your website with SSL/TLS certification is ready.
Try going to your website by entering only domain name (that is http), you will be redirect automatically to the https site.

Part 2: Auto renew your certificate

Every certificate issued by Let’s Encrypt has a validity period of 3 months. So i will try to renew it once everymonth.
The idea is to simply use crontab to run the renew command automatically.

Create the script for auto renew

# Run as root
touch ~/renew_letsencrypt_certificates.sh

Paste following content into that file:

( 
echo ""
echo "------------------------------"
date

certbot renew -q

) >> /var/log/renew_letsencrypt_certificates.log 2>&1

The script prints a date, so that a timestamp is logged for an easier debbuging. Then followed by certbot renew -q which is the heart of this script, it renews all certificate managed by certbot quietly, without any interactive question.
All error and output (2>&1) are written to the log file.

Add execute permission to the file

chmod u+x ~/renew_letsencrypt_certificates.sh

Set a schedule to execute this task

Certbot website guides users to run this script at 0 and 12 o’clock, plus a random amount of time in the range of 1 hour. So i will avoid this time range and choose an other time slot.

# Run as root
crontab -e
0 15 26 * * /root/renew_letsencrypt_certificates.sh

Because my certificate is issued on 26, so I decide to renew it on day 26 each month. And run it at 15:00.

With this setup, my website will have HTTPS certificate automatically.