Skip NavigationGo to FooterGo to Site Control
Liwen Duan's Logo

How to secure your website using certbot, Cloudflare, and nginx

HTTPS becomes mainstream these days, it is good for a web administrator like you to know how to secure your website.

Last update on 2022-02-18


Website security is heavily valued in current days. Data from ISRG's ( Internet Security Research Group ) annual report shows today over 83% of websites are encrypted. Having your website encrypted using an SSL certificate can bring you really good benefits. Securing you - the website owner, and your audience. This is because the core function of an SSL certificate is to protect communication between servers and clients, encrypt all data coming from and to your server. It will give hackers a hard time finding out information valuable to them.

It used to be websites involved payment is preferred to install an SSL certification. Obviously, everyone knows money needs to be protected. Also, at the time, implementing a secure connection is complicated, and acquiring a certificate is expensive. With the effort of many companies and organizations, people start to see the importance to secure their servers and websites. There are more tools to make secure websites become easy. And there are free certificates available to us. There is no reason not to secure your website with SSL Certificates.

I start to secure my website in 2017 using Let's Encrypt's certificates. There might be no audience to visit my site, but I think having implemented the feature is needed, showing my care in cutting edge technologies, my potential audience, and myself. At the time, I don't know how to use script and API to automate the process, web interfaces are my friends, I still manage to do it. Now I have some knowledge of the command line, I learn it is easy to do. So I kept doing it, securing all of my web services to the world.

But how?

Basically, you need a domain and a Linux server (Windows Server has GUI software, so it is easy to figure it out 🙂). Here is the slightly detailed thing you need:

What you need

Here is the setup I have:

I ...

  • use a Debian VPS with a public IP address (or open to the internet)
  • have a domain managed by Cloudflare
  • have a website available to be secure

Don't worry If you don't have the exact environment, you can easily adapt to your environment with some knowledge.

What we are going to do?

Basically, we need to:

  • Install the software
  • Have our website available.
  • Request our certificates
  • Install the certificate to our web server. Job done.

Install Nginx

Software is our friend to achieve our goal, so we are going to install some.

First, we need a webserver to host and provide our website to the world. I like Nginx because it is powerful and easy to use.

1 sudo apt install nginx

It is easy to configure a website using Nginx. After installing it, everything related to Nginx is in /etc/nginx folder.

Let's say your website is available in /home/lwdStudio/lwdSite/public folder. To make this website available to Nginx, you need to let Nginx know where is your site. To do that, we need to create a file at /etc/nginx/sites-available folder.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 server { # Listen to port 80. This is the default port for HTTP. listen 80; # URL you want your website available at. server_name; # Where your website is located. root /home/lwdStudio/lwdSite/public; # index file Nginx should look for. index index.html; # if you have an error page available, configure it. the location is the relative path to the root we configured before. error_page 404 /404.html # return 404 if no content is available at the slug. location / { try_files $uri $uri/ =404; } }

This is what a basic Nginx configuration file should look like. If you want to learn the configuration file in detail, Nginx provide an default file with detailed comment for you to look at. Right now don't worry about 443 and SSL things.

To enable your Nginx setting, you need to have your configuration file available in /etc/nginx/sites-enable folder. Instead using command like cp or mv, I recommend to use ln to create system link.

To create link of your lwdSite.conf file, issue this command:

1 sudo ln -s /etc/nginx/sites-available/lwdSite.conf /etc/nginx/sites-enable/lwdSite.conf

To apply your modified Nginx configuration. I recommend let Nginx verify conf file syntax:

1 sudo nginx -t

Then applied your Nginx configuration via reload:

1 sudo nginx -s reload

Now your basic Nginx configuration is ready.

Let's install Certbot

Certbot is software made by Electronic Frontier Foundation (EFF) to help you get a certificate automatically from Let's Encrypt, a certificate authority (CA) willing to provide the world with free certificates.

Certbot is a little bit complicated. This is because the community has provided many plugins to make it easy to use. We need to select some plugins to fit our use case. Here is the list of things we will install:

  • python3-certbot: Certbot itself using Python 3
  • python3: Certbot is created with Python, so we need Python 3 environment to be available in our system.
  • python3-certbot-nginx: Certbot plugin for Nginx, for install your certificated onto your Nginx configuration
  • python3-certbot-dns-cloudflare: Certbot plugin for Cloudflare

To install, issue command in your terminal:

1 sudo apt install python3 python3-certbot python3-certbot-nginx python3-certbot-dns-cloudflare

Now Certbot has been installed.

Notice: Ubuntu ships more updated versions of Certbot and all Certbot plugins, while Debian only ships old stable versions. The configuration might be different between versions, I recommend double-checking with Certbot's version as well as documentation of the exact version installed on your system.

Let Authority know you own a domain

The certificate we are going to acquire is a DV certificate. Which is a Domain Validated certificate. As the name suggests, your domain needs to be validated before a certificate can be issued. But how to verify that?

Certbot typically uses http-01 to verify domain ownership. Basically, Certbot will place a file on your website, Let's Encrypt will access the file on their behalf. They will compare the file access your server is the same they issued when requested.

What we are going to use is dns-01. The basic concept is the same, but instead, a file is been stored on your server, Certbot will use API (Application Programming Interface) to create a DNS record to store the verification information from Let's Encrypt. It also brings a benefit. Typically the person who has access to the DNS of the domain is the domain owner, Let's Encrypt allows us to acquire a wildcard certificate (like * from them.

Because creating DNS records is a sensitive activity, DNS providers like Cloudflare often require some kind of verification to ensure identity. When you tweak any setting via a web interface, you can enter your email, password, and even captcha. For a server, we use API to communicate with Cloudflare. We are not using email and password combination, we use API Key or API Token to authenticate.

⚠ At the time of writing, Debian's APT repository still not shipping with the latest version of the plugin so it still supports API Key instead of API Token. If you have a later version of the plugin installed, it is more secure to use API Token to authenticate with Cloudflare, and I recommend switching to Token if possible.

Checking certbot-dns-cloudflare 's documentation, there are these things we need to provide to authenticate our identity to Cloudflare:

  • dns_cloudflare_email: Your Cloudflare account email
  • dns_cloudflare_api_key: Your Cloudflare API Key

To get your API Key, go to your API Token page on your Cloudflare Dashboard .

You want to click the blue "View" button on the "Global API Key" line to get your API Key. If you did not know whether you used API Key before, click the "Change" button to generate a new one.

⚠ Treat your API Key the same way as your password! Keep it safe.

At your server, create a file at a secure location like ~/.secret/cf_token, and fill the parameter accordingly as below

1 2 3 # Cloudflare API credentials used by Certbot dns_cloudflare_email = [email protected] dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234

You need to restrict access to this file. Certbot will not take the credential unless the file is secure.

Issue this command to secure the file:

1 sudo chmod 600 ~/.secret/cf_token

Now you have your Cloudflare credential ready, you can move on to the next section.

Aquire certificate

Acquire certificate using Certbot needs you to issue some really long commands. Here is how I acquired the certificate for this site.

1 2 3 4 5 sudo certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials ~/.secrets/cf_token \ -d \ -d *

The first line lets Certbot only acquire the certificate. This is because Certbot only issue wildcard certificate in certonly mode.

The second line lets Certbot know to use certbot-dns-cloudflare plugin.

The third line lets Certbot know where to find our Cloudflare credential.

The last two lines are let Certbot know what domain we want to secure.

This command can also be written in one line:

1 sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/cf_token -d -d *

If everything passes, you should be getting your own Let's Encrypt certificate.

To view your Certificates, use this command:

1 sudo certbot certificates

You will have information like certificate expiration time, and certificate file location.

The very first time you start the Certbot, you will be prompt to enter an email address. This is how certificated authority (CA) knows you. They will use this email to prevent malicious activity like requesting too many certificates, and provide email notification when your certificate is about to expire.

You also need to agree with some legal stuff and marketing email requests. Make your own choice.

2021-12-27 15_20_26-~.png

Also, Certbot needs to be run as root. So be careful with what you will be doing. I do not recommend you to use root account directly due to potential risks. Instead, I recommend using sudo command. If sudo is not available on your system, you can install sudo package using your system's package manager.

Install your certificate

This probably the most shortest section and the most easiest part of this How-To Guide. Simply issue:

1 sudo certbot install

Choose Certificate and Nginx server block as prompted. Then choose Redirect to elevate all non HTTPS requests to HTTPS, you are done!

Now your certificated are automatically installed, and your site will only be served through HTTPS with encryption.

Additional things to mention because of Cloudflare.

Cloudflare is a great easy use platform to increase loading speed and provide basic security to your website. But sometimes its default security might be tricky to use. You might notice when accessing most of the Cloudflared sites, you might notice the certificate it uses is a Cloudflare certificate, not your own Let's Encrypt certificate.

2021-12-27 17_01_03-I'm Liwen Duan, I build website like this one. _ lwdSite3 and 18 more pages - Pe.png

This is because of how Cloudflare works, acting as a proxy between client and server. You want to make sure your SSL/TLS setting on your Cloudflare Dashboard is set to Full (Strict)

2021-12-27 17_04_54-Overview _ SSL_TLS _ _'s Account _ C.png

Also when the client accesses the site via the Cloudflare network, it will use that Cloudflare certificate. Cloudflare's free plan only provides a certificate for your root domain and a wildcard domain for the secondary domain. For example and * If you have a site like, your Cloudfared site will simply not work even you have acquired a certificate from Let's Encrypt.

How you will adapt?

  • RHEL based (eg. CentOS, Fedora...) and Arch-based distribution has their own respective package manager. Install the app according to how your OS works. Instead of using apt, you might have to use dnf or pacman.
  • Many major DNS services have API help you to get your certificate, install the respective DNS plugin to your Certbot. A full list of DNS plugins is available at Certbot documentation .