13. Procure and Deploy a Free Let's Encrypt SSL Certificate on an EC2 Instance 🔐☁🖥🏆🔑

While I worked at AWS during the publishing of this post / video, the views expressed here are my own and may not reflect those of my employer. Only publicly available material is used to put together the content of this article and video. The website and the Youtube videos are NOT monetized.

You can directly scroll down for the Youtube Video and Instructions used in the video are provided at the end of this article. Also while I am using an EC2 Graviton2 instance for this demo and article, the instructions should apply to any EC2 / Linux (Centos based) instance.

SSL certificates are no longer optional with most browsers automatically showing your customers a page like this on your HTTP only website.

HTTP_ERROR

This landing page is not a great experience for your customers obviously, but having your website served over HTTPS has other advantages too

  1. Keeping your customer’s data secure in transit when they use services offered by your website / app
  2. Better SEO
  3. Better user experience
  4. Mandatory for many use cases - for exampe if you are handling card payments on your website, then PCI/DSS compliance makes it mandatory (among other things) to have your website served over HTTPS

Now when you are running your workloads on AWS, it is preferable to use ACM or Amazon Certificate Manager to procure certificates (which are free by the way) for your application. However ACM certificates cannot be directly deployed on EC2 instances and require a load balancer (ALB) in front of your EC2 instance(s).

For many small customers and hobby projects a load balancer may not be necesary and you may just want to run your website / blog / application on an EC2 instance.

Now if you want to protect your website / blog / application with SSL, Let’s encrypt is the preferred way of procuring and installing SSL certificate on your instnce. What’s more, it is free.

And since a video is worth a billion words 😀, here’s a video explaining how to do it. But before you click on it here’s what we are trying to do

  1. We have an EC2 instance with an application running on port 3000
  2. We want to install nginx and use it as reverse proxy to this application
  3. We want to obtain and install an SSL certificate on nginx
  4. We want to then access nginx and the application on this instance only over HTTPs.

Ok off to the video - also below the video are all the important instructions used in the video.

Check it out.

DEMO | AWS EC2 | Deploy Let’s Encrypt Free SSL Certificate

Please watch in full screen or on youtube directly



Commands used in the video

# Install and start nginx
sudo amazon-linux-extras install nginx1
sudo service nginx status
sudo service nginx start

# Install dependencies
sudo yum install augeas-libs

# Set up a Python virtual environment
sudo python3 -m venv /opt/certbot/
sudo /opt/certbot/bin/pip install --upgrade pip

# Install Certbot
sudo /opt/certbot/bin/pip install certbot certbot-nginx

# Create link to Certbot so that you can run the certbot command directly
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot

# update your Zone entry / entries for domains you are getting cert for.

# Get Certificte, using one of the following commands
# second command also deployes the certificate
sudo certbot certonly --nginx

# Or

sudo certbot --nginx -d <your-domain> -d <your-additional-domain>

# Setup renewal and test if that works
echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew -q" | sudo tee -a /etc/crontab > /dev/null
sudo certbot renew --dry-run

# update /etc/nginx/nginx.conf
# add following lines below line include /etc/nginx/default.d/*.conf;
# please replace your.domain.com with your domain/subdomain URL
        listen 443 ssl;

        # RSA certificate
        ssl_certificate /etc/letsencrypt/live/your.domain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/your.domain.com/privkey.pem;

        include /etc/letsencrypt/options-ssl-nginx.conf;

        # Redirect non-https traffic to https
        if ($scheme != "https") {
                return 301 https://$host$request_uri;
        }

# restart nginx
sudo service nginx restart 

# SSL Procuring and installation is done if the https URL is working.

# Optional
# if you have an application that you want to reverse proxy into 
# assuming the application is running on port 3000
# add following lines below  listen 443 ssl;
        location  / {
                add_header 'Access-Control-Allow-Origin' '*'; 
                proxy_set_header X-Forwarded-Host $host; 
                proxy_set_header X-Forwarded-Server $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://localhost:3000;
        }


Reference / Further reading

https://certbot.eff.org/lets-encrypt/otherpip-nginx
https://www.nginx.com/blog/using-free-ssltls-certificates-from-lets-encrypt-with-nginx/

Thank you for reading through, Please share if it’s useful to someone.

-Nikhil

comments powered by Disqus