Ubuntu VPS Setup SSL with Nginx using Let's Encrypt
Learn how to configure Nginx for HTTPS using Let's Encrypt. We will obtain a standalone SSL certificate from Let's Encrypt using Certbot. We will also go over what a standalone certificate is and how Certbot can be used to automatically and manually configure Nginx for HTTPS.
Table of Contents 📖
- What is Let's Encrypt?
- What is Certbot?
- Installing Certbot with Snap vs. APT
- Nginx Redirect HTTP to HTTPS
- Generating a Certificate with Certbot
- Configuring Nginx for HTTPS
What is Let's Encrypt?
Let's Encrypt is a free and open certificate authority. Certificate authorities store, sign, and issue digital certificates. Digital certificates can be used to authenticate a website's identity and encrypt its connections.
What is Certbot?
Certbot is an automated certificate management tool. We can use it to obtain digital certificates from certificate authorities like Let's Encrypt.
Installing Certbot with Snap vs. APT
Certbot says that the best way to install it is to use snapd. Snapd stands for snap daemon and it is the background service that manages and maintains snaps, packages that are secure and easy to install. However, if you are using a VPS, snapd won't always work. This is because snaps rely on certain Linux kernel features that aren't available under containerized servers like those running under OpenVZ. You can check if your server is running under OpenVZ by running the following command.
sudo systemd-detect-virt
If OpenVZ is being used, the string openvz will be printed to the console. Because of this, we will use Ubuntu's Advancted Packaging Tool (APT) to install Certbot.
sudo apt install certbot
The only difference with using APT is that it won't be the fully up to date version of Certbot, but it should work just fine. It is also common to install the Certbot plugin package python3-certbot-nginx when using Nginx.
sudo apt install python3-certbot-nginx
This is because this plugin allows Certbot to manually update the Nginx configuration to handle SSL. However, for this demonstration we will be editing the Nginx configuration manually.
Nginx Redirect HTTP to HTTPS
Now lets configure Nginx to redirect all HTTP traffic to HTTPS. No matter where this configuration is made, it needs to end up in nginx.conf, Nginx's main configuration file. HTTP typically runs on port 80 while HTTPS typically runs on port 443.
server {
listen 80;
server_name wittcode.com;
location / {
return 301 https://$host$request_uri;
}
}
Here, we use the return directive to redirect the request to HTTPS. The return directive is used to change part of the URL in a client request. Note how the protocol is being moved from HTTP to HTTPS. The 301 status code means Moved Permanently and indicates that the requested resource has been moved to the URL we provide.
- $host - Nginx variable that represents the name from the request line, or host name from the 'Host' request header field, or the server name matching a request.
- $request_uri - Nginx variable that represents the original URI in the request.
Generating a Certificate with Certbot
Now lets use the Certbot package to obtain a certificate from Let's Encrypt.
certbot certonly --standalone -d <your_domain> --email <your_email>
- certbot - Package used to automatically configure HTTPS using Let's Encrypt.
- certonly - Short for certificate only. Obtains a certificate without installing it anywhere.
- --standalone - Spins up a standalone web server on port 80 to pass the http-01 challenge. Passing this challenge proves that we control the domain.
- -d - The domain we want to obtain a certificate for. You can add multiple -d options for multiple domains.
- --email - Email used for registration and notifications.
This command will be successful if you own the domain supplied to -d and are on the web server that this domain points to. If the command is successful, Certbot will place certificates and keys in the directory /etc/letsencrypt/live/<your_domain>.
ls /etc/letsencrypt/live/<your_domain>.com/
README cert.pem chain.pem fullchain.pem privkey.pem
- cert.pem - The server certificate file.
- chain.pem - The intermediate certificate file.
- fullchain.pem - Combination of cert.pem and chain.pem.
- privkey.pem - The private key for the certificate.
The PEM extension stands for privacy-enhanced mail and is a file format for storing crytographic keys, certificates, etc. The two most important files for Nginx are privkey.pem and fullchain.pem.
Configuring Nginx for HTTPS
To create an HTTPS server with Nginx, we first have to include the ssl parameter to the listen directive on port 443, the standard port for HTTPS.
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name <your_domain>;
}
Next, we need to tell Nginx the location of the SSL certificate and private key that we obtained with Certbot. We can do this with the ssl_certificate and ssl_certificate_key directives.
ssl_certificate /etc/letsencrypt/live/wittcode.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/wittcode.com/privkey.pem;
- The ssl_certificate directive accepts a file with an SSL certificate in the PEM format.
- The ssl_certificate_key directive accepts a file with a private key in PEM format.
Finally, just make sure to reload or start Nginx with this configuration and HTTPS will be enabled.