Contents

Installing and Configuring CertBot

This is the third part of a series of 3 posts where I will be installing CertBot to enable HTTPS on NGINX and automate the renewal.

This is the third of 3 posts where I will be:

In this, the last part of this guide, we will:

  • Install CertBot to get certificates from LetsEncrypt for our site
  • Move the default CertBot directory to a different one
  • Tweak the NGINX configuration to reflect the SSL certificates
  • Redirect all request to HTTPS

Before we start you need a domain name, you can get one from freenom.com for free to start with or just to practice; this domain should be pointing to your server public IP address. For now let’s assume your domain is example.com.

Updating your server block

In the firt part of the guide we created a simple server block file called default.conf in /etc/nginx/sites-available/ it looks like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

I have removed the commented lines for convinience. We need to update that to reflect that the server is called example.com, for that modify the server_name to example.com, to look like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
server {
    listen       80;
    server_name  example.com;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

Check the config and restart NGINX if all is ok.

1
$ sudo nginx -tt && sudo systemctl restart nginx.service

Now you should be able to see your server if you access example.com from your browser.

Preparing the Enviroment

The following step, is to prepare the server to deal with the certificate request, this will help in the future to do the automatic renewal and to keep all files in the right folders.

Create a directory named _letsencrypt in /var/www/, as:

1
2
$ sudo mkdir -p /var/www/_letsencrypt
$ sudo chown www-data /var/www/_letsencrypt

Let’s create the snipped of config to deal with the folder redirection, create a file named letsencrypt.conf in /etc/nginx/snippets/ and add the following:

1
2
3
4
# acme-challenge redirection
location ^~ /.well-known/acme-challenge/ {
    root /var/www/_letsencrypt;
}

Add the following line at the end of the server declaration in the default.conf server block:

1
include snippets/letsencrypt.conf;

It should look like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
server {
    listen       80;
    server_name  example.com;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
    include snippets/letsencrypt.conf;
}

Check the config and restart NGINX if all is ok.

1
$ sudo nginx -tt && sudo systemctl restart nginx.service

Installing

To install support for CertBot we can use the standard module from the repository available in your distro, do the following, update apt with:

1
2
$ sudo apt update
$ sudo apt install certbot

Requesting a Certificate

To request the certificate we just need CertBot and execute the below command. there are few CertBot plugins that can make all the changes for us and automate the certificate installation (e.g. python3-certbot-nginx), but we don’t that becasue we want to control the details in the configuration, and the config generated by the nginxconfig.io will help us on that.

For now lets just ask for the certificate to be genrated and saved in our server with:

1
$ sudo certbot certonly --rsa-key-size 4096 --webroot --agree-tos --email <your_email_here> -w /var/www/_letsencrypt -d example.com -d www.example.com

<your_email_here> should be your email address, it will be used to sent you reminders about the renewal of the certificates. You can include the flag --no-eff-email if you don’t want to receive the reminders. In this case we are requesting a certificate for the root domain and the www sub-domain. you can include more if you need like dev.example.com.

With that CertBot generate and save the certificates to the directory /etc/letsencrypt/live/example.com, it should contain all files you need:

1
2
3
4
5
cert.pem
chain.pem
fullchain.pem
privkey.pem
README

Including the certificates in your server block

In this section we will include the certificates and the redirection block for all the HTTP requests to be redirected to HTTPS, for that let’s update the configuration as below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
server {
    listen                  443 ssl http2;
    listen                  [::]:443 ssl http2;
    server_name             example.com;
    root                    /usr/share/nginx/html;

    # SSL
    ssl_certificate         /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

    # index.html fallback
    location / {
        try_files $uri $uri/ /index.html;
    }

}

# HTTP redirect
server {
    listen      80;
    listen      [::]:80;
    server_name example.com;
    include     include snippets/letsencrypt.conf;

    location / {
        return 301 https://example.com$request_uri;
    }
}

Check the config and restart NGINX if all is ok.

1
$ sudo nginx -tt && sudo systemctl restart nginx.service

Now you should be able to see your server via HTTPS if you access https://example.com from your browser.

Certbot Auto-Renewal

To test the renewal process, you can use the dry run option of certbot, for that trigger:

1
$ sudo certbot renew --dry-run

You should not have errors, if you do check that all the values are correct in the initial command to create request the certificate sudo certbot certonly --rsa-key-size 4096 --webroot --agree-tos --email [email protected] -w /var/www/_letsencrypt -d example.com -d www.example.com.

The automated process is a cron job available at /etc/cron.d, but if you are using systemd the job is scheduled via a timer task, you can see the task with:

1
$ sudo systemctl list-timers --all

and for details use sudo systemctl show certbot.timer.

Conclusion

By now you have a funcional site running in you NINGX, but you should now tweak some security features and the general configuration to look more like the ones here.

You will need to:

  • Create the file /etc/nginx/snippets/general.conf and include the sugested content.
  • Create the file /etc/nginx/snippets/security.conf and include the sugested content and:
  • Add the directive add_header X-Frame-Options "SAMEORIGIN" always;
  • Add the directive add_header X-Permitted-Cross-Domain-Policies "none";
  • Update the file /etc/nginx/sites-available/example.com.conf as sugested, but:
  • The proposed config activates HTTP2.
  • The document root will be /var/www/example.com change as needed.
  • Remember that your snippets of code are at snippets not at nginxconfig.io.
  • The methods allowed are only GET, POST and HEAD, everything else will receive a 405.
  • There will be log files per server block, example.com.access.log and example.com.error.log will be the logs files for example.com.
  • Update the file /etc/nginx/nginx.conf as sugested, but:
  • Remember to adjust worker_connections.
  • Below the directive client_max_body_size I like to include the below, but adjust as you need:
    • log_not_found off;
    • keepalive_requests 100;
    • keepalive_timeout 65;
    • open_file_cache max=100;
    • server_names_hash_bucket_size 64;
    • server_name_in_redirect off;
  • Adjust the Mozilla Intermediate configuration section to include ssl_prefer_server_ciphers off;, it is not requiered but I will say include it.

With those changes you should be able tyo check your site with SSLLabs Server Test tool and get an A+.

Buy me a Coffee
Hope you find this useful, if you have any question please visit my twitter @bigg_blog and if you have a couple of pounds buy me a coffee.
G