In this guide we’ll learn how to configure HTTPS on a Nginx web server using a free certificate obtained from LetsEncrypt.org.
- If you’re running Apache instead of Nginx, check out this guide....)
- The instructions that follow assume you already have a site configured on a Nginx server that loads via regular http. If you don’t, start here: Configuring sites/URLs on a Nginx web server.
- Finally, if you’re new to HTTPS and want a quick overview of the “Why” before jumping into the “how”, check out: What is HTTPS (SSL) and why every site should use it.
Certificate Authority - Let’s Encrypt
To enable HTTPS, we need a certificate from a Certificate Authority (CA).
These can be purchased and range in cost from about $5 upwards of $100+ (example price/tier options from Namecheap...).
Alternatively, we can get a free certificate from Let’s Encrypt which is a non-profit Certificate Authority. (Why/how Let’s Encrypt is free...)
Using Let’s Encrypt will allow us achieve the goal of encrypting our data transfer, however, it does not offer the same level of domain/server validation that a paid-for certificate will. You should consider a paid-for certificate in any situation where you’re collecting/processing sensitive data (personal information, monetary transactions, etc.) and/or you want to communicate to your users that your site is secure and trustworthy.
Certbot
Let’s Encrypt certificates can be set up using the command line tool Certbot.
Certbot can be used on both Nginx and Apache web servers and it’s supported on various Linux distributions such us Ubuntu, Debian or CentOS. In this example, we’ll work on an Ubuntu server running Nginx.
To determine if Certbot is installed on your server, run the following command:
> certbot --version
If this returns an error message about the command not being found, you’ll need to install Cerbot. The Certbot web site has good instructions for installation on a variety of server types.
Initiate a new certificate
Once you’ve determined Certbot is installed and you know what site(s) you want to set up HTTPS for, run the following command to start the process:
> sudo certbot
The first time you run Certbot it will ask you for an email, to agree to their terms of services, and specify whether or not you will receive newsletter emails from them.
Next it will ask you what site(s) you want to activate HTTPS for, pulling from the existing sites you’ve configured on your server. You can choose an individual site or leave it blank and hit enter so HTTPS will be set up for all the sites on your server.
In my example, I’ll choose option 1
to set up HTTPS for the domain demo.codewithsusan.com
:
After hitting enter, it will proceed to set up your certificate and then prompt you to choose whether regular http traffic should be left alone or redirected to https; I suggest going with redirect and choosing option 2
:
After the above question, you’ll see the final confirmation details:
Once the above is complete, you should now be able to access your sites via https.
How it works
If you open the site configuration file for the domain you just enabled HTTPS for, you should see new details were added for https. For example, if I open /etc/nginx/sites-available/demo.codewithsusan.com
I see the following:
Renewing certificates
Let’s Encrypt certificates expire after 90 days. As part of the above setup process, though, configurations were put in place to automatically renew your certificates for you.
This happens via the cron job found at /etc/cron.d/certbot
.
Long story short, there’s no action you need to take to maintain a Let’s Encrypt certificate once its been installed.
Removing certificates
You can revoke an existing certificate following this command pattern:
> sudo certbot delete --cert-name yourdomain.com
Once that is complete, you should update your site’s config:
- Set it to listen on port 80 (http) instead of 443 (https)
- Remove any line commented as
# managed by Certbot
- Remove the server block redirecting all traffic from http to https
Finally, restart your server to make the changes take effect: systemctl restart nginx