Tuesday, August 23, 2022

How to setup auto renewable free SSL certificate using Lets Encrypt and Nginx on Ubuntu machine

In this tutorial, we are going to set up free SSL auto-renewable Let's Encrypt along with Nginx.


Before we start setup, first make sure your domain e.g example.com is pointed to the server's public IP address. You can set up and point this configuration from the dashboard of your domain service provider.

Connect to the remote server:

First SSH into the remote server where we want to set up the SSL.

If you are using a server password to connect, use the following command

sudo ssh server_username@ip_address

Here use your server username and server IP address to connect. For example ubuntu@34.344.56

If you are using a .pem file or other private keys to connect to a server then use the following command

sudo ssh -i path_to_pem_file server_username@ip_address

Install Nginx:

First, let's install Nginx on the server using the following commands.

sudo apt-get update
sudo apt-get install nginx

If nginx got successfully installed, then use the following command to verify.

nginx -v
nginx version: nginx/1.18.0 (Ubuntu)

Or we can verify by checking the status

sudo systemctl status nginx

Setup Nginx Configuration:

Now let's configure the Nginx for our domain. For this navigate to the Nginx directory

cd /etc/nginx/sites-available

Here, if we use the ls command we can see the default file for configuration. We will create a new file for our domain to configure for e.g 360learntocode.com, you can create using your domain name.

sudo vim 360learntocode.com

Now the new empty file is open lets edit and inserts the configuration by entering Shift + i

server {
      server_name 360learntocode.com;

      location / {
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   Host $http_host;
        proxy_pass              http://568.19.34.63:8080;

Make sure to replace 360learntocode.com with your domain name and http://568.19.34.63:8080 with your IP address and the port in which your application is running.

Now save the configuration. Enter Esc and type :wq and hit Enter.

Now, symlink this file with the directory “sites-available” in our Nginx for this navigate to sites-available

cd /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/360learntocode.com /etc/nginx/sites-enabled/

To check the Nginx configuration use the following command

sudo nginx -t

We are supposed to see the output as below

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

Reload the Nginx to reflect the changes:

sudo systemctl reload nginx

If we try to open our domain, we can see the Nginx 502 Bad Gateway if our application is not running otherwise we will see the running application.

Setup SSL Certificate:

For the SSL certificate, we are using the let's encrypt and certbot client. For more detail check let's Encrypt and Certbot

- Install Certbot client

Use the following commands to install certbot client

sudo apt-get update
 sudo apt-get install python3-certbot-nginx

Now, the certbot is successfully installed on our server. Let's create an SSL certificate for our domain

sudo certbot --nginx -d 360learntocode.com

Note: use your own domain name. Follow the steps asked afterward.

Here are some sample examples screens.

Now, let's reload the Nginx so that our configuration changes will reflect.

sudo systemctl reload nginx

If we load our domain URL then it will open over HTTPS.

If you want to see the overall configuration setup, please open the file that we created previously i.e 360learntocode.com inside /etc/nginx/sites-available/, there we can see all the setup done. The sample file looks like as below.

server {
      server_name 360learntocode.com;

      location / {
        proxy_set_header   X-Forwarded-For $remote_addr;
        proxy_set_header   Host $http_host;
        proxy_pass              http://568.19.34.63:8080;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/360learntocode.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/360learntocode.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

server {
    if ($host = 360learntocode.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

      server_name 360learntocode.com;
    listen 80;
    return 404; # managed by Certbot


Here, the auto-renew script is managed by certbot client so we don't have to worry about the SSL expiration. To verify the auto-renew scripts navigate to the script file.

cd /etc/cron.d/
sudo vi certbot

In the certbot file, we can see the auto-renew script as below added by cerbot client

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

Thanks for following the tutorial, Happy coding !!