Add Https to website using Let's Encrypt to Nginx configured as a reverse proxy on Ubuntu
Step by step guide for adding Https to website using Let's Encrypt to Nginx configured as a reverse proxy on Ubuntu
Written By
Dipesh Wagle
Published on October 26, 2018
To enable HTTPS on your website, you need to get a certificate (a type of file) from a Certificate Authority (CA). Let’s Encrypt is a CA. In order to get a certificate for your website’s domain from Let’s Encrypt, you have to demonstrate control over the domain. With Let’s Encrypt, you do this using software that uses the ACME protocol, which typically runs on your web host.
Let’s Encrypt uses the ACME protocol to verify that you control a given domain name and to issue you a certificate. To get a Let’s Encrypt certificate, you’ll need to choose a piece of ACME client software to use.
We use Certbot as ACME client. It can simply get a cert for you or also help you install, depending on what you prefer. It’s easy to use, works on many operating systems and has great documentation.
The first thing to before adding SSL in your website using Let's Encrypt make sure that you have an ubuntu server running and have ssh access to it. Also, make sure that you have a domain that's pointed to the server.
Install Lets Encrypt
To install Let's Encrypt on ubuntu first add the repository.
For Ubuntu 16.04
sudo apt-get install software-properties-common python-software-propertiessudo add-apt-repository ppa:certbot/certbotsudo apt-get update
For Ubuntu 18.04
sudo apt-get install software-properties-commonsudo add-apt-repository ppa:certbot/certbotsudo apt-get update
Then install LetsEncrypt which contains that contains cerbot and other libraries needed.
sudo apt-get install letsencryp
Verify ACME challenge using Nginx
To verify that we have control over a domain first we need to pass the ACME challenge. For that we will configure Nginx to catch all request to /\.well-known/acme-challenge/
and host it in /var/www/letsencrypt
.
Change you're vhost so it looks like this. You can use default one located in /etc/nginx/sites-available/default
server {listen 80 default_server;listen [::]:80 default_server;location ~ /\.well-known/acme-challenge/ {allow all;root /var/www/letsencrypt;try_files $uri =404;break;}
Let's create folder /var/www/letsencrypt
to host the challenge.
mkdir /var/www/letsencrypt
Let's check out Nginx setting are valid by running
sudo nginx -t
If you get message like this you're ready to go.
nginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful
Now let's reboot our nginx sever to apply the changes
sudo service nginx reload
Generating Let's Encrypt SSL
After setting up Let's Encrypt now we will generate the SSL certificates. I'll use ssl.example.com
as an example domain name, use your own domain.
Now use this command to generate the SSL replace the following fields with your own fields.
-
mail@example.com with your own email address
-
ssl.example.com with your own domain
sudo letsencrypt certonly -a webroot --webroot-path=/var/www/letsencrypt -m mail@example.com --agree-tos -d ssl.example.com
You should see the congratulations message after this step.
Adding SSL to Nginx
Now let's configure our virtual host file with new SSL certificates. I'll use default config at /etc/nginx/sites-available/default
but you can use your own, just replace ssl.example.com with your own domain name.
server {server_name ssl.example.com;listen 443 ssl;ssl on;ssl_certificate /etc/letsencrypt/live/ssl.example.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/ssl.example.com/privkey.pem;location ~ /.well-known {root /var/www/letsencrypt;allow all;}}
Reverse proxy on Nginx
If you've got your web server running on localhost on your sever you can use Nginx to proxy all the request to the web server. For example I have a node server running at localhost:8000
and you can use this config to pass all request to local web server. Just replace the port inside location /
with your server's port number.
server {server_name ssl.example.com;listen 443 ssl;ssl on;ssl_certificate /etc/letsencrypt/live/ssl.example.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/ssl.example.com/privkey.pem;location ~ /.well-known {root /var/www/letsencrypt;allow all;}location / {proxy_pass http://127.0.0.1:8000;proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection 'upgrade';proxy_set_header Host $host;proxy_cache_bypass $http_upgrade;}
Force all requests to https
If you want all the HTTP request to be forced into HTTPS request you can add this block in your Nginx config file.
server {listen 80 default_server;listen [::]:80 default_server;server_name ssl.example.com;return 301 https://$host$request_uri;}
Automate renewal of SSL certificates
The SSL certificates issued by Let's encrypt is only for 90 days. You can use following commands to automate the renewal of the certificates.
Create a script to run every day that checks and renews the certificate if they expire.
sudo touch /etc/cron.daily/letsencrypt
And set it's permission.
sudo chmod +x /etc/cron.daily/letsencrypt
Now add the following content to the /etc/cron.daily/letsencrypt
file.
Ubuntu 16.04
#!/bin/bash/usr/bin/letsencrypt renew && /etc/init.d/nginx reload
Ubuntu 18.04
#!/bin/bash/usr/bin/letsencrypt renew --renew-hook "/etc/init.d/nginx reload"
Conclusion
Adding SSL certificates makes your website more secure and make the site look more secure to search engines and even the user. Let's Encrypt enables us to freely do it. So I think to do it essential of any web applications or websites.