Set up HTTPS on EC2 running Nginx without ELB

2014-07-15 2 min read

    I recently needed to set up HTTPS for my side project, better404.com. Amazon makes it easy to set up by uploading it directly to an ELB but in my case it’s hosted on a single AWS instance so I didn’t want to pay for an ELB that would be more expensive than my one instance. I’ve heard horror stories and expected the worst but it turned out surprisingly easy. Hopefully these steps can help someone else out.

    • Get an HTTPS certificate. I bought three certificates from Namecheap a couple of months ago when they were running a promotion.
    • Go through the certificate generation process. I found this guide that explains how to do it detail and worked well for me. The only things I had to change where the Nginx certificate configuration folder path (/opt/local/nginx/conf/certs => /etc/nginx/certs/) and replacing the filenames to be more specific (domain.* to better404.*). Note that this process is not immediate and you will need to send the contents of your CSR file to the SSL provider and they will respond back with the SSL certificate to use.
    • Enable SSL in Nginx. The previous guide provides some information here and I’m including the relevant parts from my configuration. I chose to redirect all traffic to HTTPS rather than supporting both simultaneously.
      #Nginx config
      server {
          listen *:80;
          server_name www.better404.com;
          rewrite        ^ https://$server_name$request_uri? permanent;
      }
      
      server {
          listen *:80;
          server_name better404.com;
          rewrite        ^ https://$server_name$request_uri? permanent;
      }
      
      server {
          listen *:443 ssl;
          server_name better404.com;
      
          ssl on;
          ssl_certificate certs/better404.pem;
          ssl_certificate_key certs/better404.key;
    • Allow Nginx to bind to the IP address. One thing that’s not mentioned in the guide and required a bit of digging around is that you need to allow Nginx to bind to the non local IP address - otherwise it can only access the private IP address set by AWS. There’s a quick guide on how to do this I found on StackOverflow.

    If you have any questions feel free to leave a comment and I’ll try to help out.