Secure Your Website For Free Using Let‘s Encrypt SSL Certificates on Amazon EC2

As a developer, you know the importance of securing your website and web applications with HTTPS. Using SSL/TLS encryption protects your users‘ sensitive data like passwords and credit card numbers as it‘s transmitted over the internet. It also helps build trust by showing visitors your site is authentic and they can feel safe entering their information.

However, purchasing and renewing SSL certificates from a certificate authority can be expensive, especially for small websites or side projects. Enter Let‘s Encrypt – a free, automated, and open certificate authority provided by the non-profit Internet Security Research Group. And Certbot, a tool to automate the process of fetching and installing Let‘s Encrypt certificates on your web server.

In this guide, I‘ll walk you through the step-by-step process of using Certbot to install a free Let‘s Encrypt SSL certificate on an Amazon EC2 instance running the NGINX web server. By the end, you‘ll have your site fully secured with HTTPS encryption. Let‘s get started!

Prerequisites

Before we dive into the setup process, make sure you have:

  • An AWS account
  • An Amazon EC2 instance running NGINX
  • Registered domain pointing to your EC2 instance
  • Access to update your domain‘s DNS records

Step 1: Open Ports 80 and 443

The first step is to ensure traffic on ports 80 (HTTP) and 443 (HTTPS) can reach your EC2 instance. Certbot uses these ports to verify your domain and generate the SSL certificates.

In the AWS Management Console, navigate to EC2 > Security Groups and find the Security Group for your EC2 instance. Edit the inbound rules to add a rule allowing HTTP traffic on port 80 and HTTPS traffic on 443 from any source (0.0.0.0/0).

Inbound rules allowing HTTP and HTTPS traffic

Note that I wasted quite a bit of time troubleshooting why I couldn‘t generate a certificate, only to realize I hadn‘t opened port 443. Don‘t make the same mistake!

Step 2: Point Domain to EC2 Instance

In order for Let‘s Encrypt to generate a certificate for your domain, it needs to point to your EC2 instance. The simplest way is to create a CNAME record mapping your domain to your instance‘s public DNS name.

In your domain registrar or DNS provider‘s control panel, add a new CNAME record pointing your domain (e.g. www.yourdomain.com) to your EC2 instance‘s public DNS name. You can find the public DNS in the EC2 console on your instance‘s description tab.

CNAME record for domain pointing to EC2 public DNS

It can take some time for DNS changes to propagate. You can use a tool like What‘s My DNS to check when your new CNAME record has taken effect.

Step 3: Install Certbot

With the prerequisites out of the way, you‘re ready to install Certbot on your EC2 instance. The exact install process depends on your operating system and web server.

Certbot provides a handy guide where you can select your web server and OS to get customized instructions. For example, if you‘re running Ubuntu 20.04 with NGINX, the steps are:


sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

If you‘re using an older OS, you may need to use the certbot-auto script instead:


wget https://dl.eff.org/certbot-auto
sudo mv certbot-auto /usr/local/bin/certbot-auto
sudo chown root /usr/local/bin/certbot-auto
sudo chmod 0755 /usr/local/bin/certbot-auto

Step 4: Generate SSL Certificates

With Certbot installed, you‘re ready to generate your certificates. First, stop any process using ports 80 and 443 on your instance (like NGINX or Apache). Certbot needs to bind to these ports to complete its challenges.

Then run this command, replacing the domain name with your own:


sudo certbot certonly --standalone -d www.yourdomain.com

Certbot will prompt you to enter an email address for renewal reminders and notices. Then it will run a challenge to verify you control the domain. If successful, it will generate your certificate files and place them under /etc/letsencrypt/live/www.yourdomain.com/

The –standalone flag tells Certbot to bind its own web server to ports 80/443 to complete the challenge. If you‘re unable to stop your existing web server, you can also use the webroot plugin. See Certbot‘s docs for details on other plugins and options.

Certbot successfully generating SSL certificates

Step 5: Configure NGINX to Use SSL

Now that you have your SSL certificate files, you need to configure your web server to use them. Open your NGINX configuration file, typically located at /etc/nginx/nginx.conf.

Update the configuration to tell NGINX to listen on port 443, use your SSL certificate and key files, enable HSTS, and redirect any HTTP requests to HTTPS:


http {
  server {
    listen 80;
    server_name www.yourdomain.com;
    return 301 https://$host$request_uri;
  }  

server { listen 443 ssl; server_name www.yourdomain.com;

ssl_certificate /etc/letsencrypt/live/www.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.yourdomain.com/privkey.pem;

ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;

add_header Strict-Transport-Security "max-age=63072000" always;

location / {
  proxy_pass http://localhost:3000;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
} 

}
}

This configuration enables HSTS which tells browsers to always use HTTPS for future requests to your domain. It sets up a strong SSL configuration using only TLS 1.2 and 1.3. The location block proxies requests to an app server running on the same instance at port 3000 – update this to match your app‘s URL and port.

After saving your changes, test your NGINX configuration with:


sudo nginx -t

If the syntax is ok, restart NGINX to apply the config:

  
sudo systemctl restart nginx

At this point, you should be able to visit your domain and see the secure padlock icon in your browser!

Website successfully loading over HTTPS with valid certificate

Step 6: Auto-Renew Certificates

Let‘s Encrypt certificates are valid for 90 days. To avoid them expiring and breaking your HTTPS connection, it‘s important to set up automatic renewal.

To handle this, you can create a cron job to run Certbot‘s renew command daily. Open your crontab with:


sudo crontab -e  

Add this line, which runs the renewal process every day at noon:


0 12 * * * /usr/bin/certbot renew --quiet

The renew command checks if your certificates are due to expire soon and renews them if so. The –quiet flag prevents it from printing output unless it takes an action.

That‘s it – you now have your certificates renewing automatically! You‘ll get email notifications from Let‘s Encrypt when a renewal succeeds or fails.

Troubleshooting Common Issues

While the setup process is usually smooth, there are a few common issues you may encounter:

  • Certbot fails to bind to ports 80/443: Make sure your EC2 Security Group allows inbound traffic on these ports and that no other process is using them. Stop your web server before running Certbot.

  • Certificate requests hit a rate limit: Let‘s Encrypt enforces rate limits to prevent abuse. For most cases, it allows 50 new registrations per domain per week. If you hit a limit, wait a week before trying again. Use the –dry-run flag to test without affecting limits.

  • Browser warnings even after installing certificate: It can take some time for browsers to recognize your new certificate. Wait a few minutes and hard refresh (Ctrl + Shift + R). Also, double-check that your CNAME record is correct and propagated.

  • HTTPS not working for www or non-www: Make sure you included both variations when requesting your certificate from Certbot. You can use the -d flag multiple times for additional domains or use a wildcard.

If you‘re still having trouble, the Certbot community forum is a great place to get help.

Benefits of Enabling HTTPS

Congratulations, your website is now fully secured with HTTPS! By taking the time to set up SSL encryption, you‘re providing several key benefits to your users:

  • Encrypted transmission of sensitive data, protecting it from interception by third parties
  • Validation that users are interacting with your authentic website and not an impersonator
  • Improved search rankings as Google provides a slight ranking boost to HTTPS sites
  • Ability to use HTTP/2 which can significantly speed up page load times
  • Better web analytics accuracy as HTTPS referral data is preserved

Best of all, thanks to Let‘s Encrypt, you can provide this improved security and user experience for free! Certbot and Let‘s Encrypt make the process of securing your site approachable even for novice developers.

To review, in this tutorial you learned how to:

  1. Open ports 80/443 and point your domain to your EC2 instance
  2. Install Certbot and generate SSL certificates
  3. Configure NGINX to use SSL and redirect HTTP to HTTPS
  4. Set up automatic renewal of your certificates
  5. Troubleshoot common HTTPS and Certbot issues

I hope this guide was helpful in securing your own website! Feel free to leave a comment with any questions or thoughts. And if you found it useful, please share it with your network to help promote a more secure web for everyone.

Similar Posts