Redirecting HTTP to HTTPS in AWS

October 22, 2016 0 Comments technology, setup

I wanted an easy way in AWS (e.g. using an Elastic Load Balancer) to rewrite/redirect a URL in Elastic Compute Cloud (EC2) but had to find an alternate solution. Having the ability to do this is useful when you're setting up a website where you want to accept a port 80 (e.g. http://www.domain.com or http://domain.com) web request, but redirect it to port 443 (https://www.domain.com). This way you can force all traffic to use SSL/TLS.

This is something I just needed to work to get the website setup, and wanted the simplest solution possible. It's fairly straight forward to do this using a reverse proxy. After examining the obvious choices (e.g. NGINX and Apache HTTP Server w/ mod_proxy), I chose lighttpd (https://www.lighttpd.net/) because it looked to be the most lightweight and easiest to configure for what I wanted to do.

Standing up lighttpd

You can install lighttpd on the command line using yum or cloud-init. Or you could use a lighttpd Docker container in AWS. I'll step through all three possibilities.

Using yum install

Installing lighttpd on Amazon Linux is simple. Simply spin up an instance . Be certain to create/assign a user key pair. SSH into the instance and install lighttpd:

sudo yum update -y  
sudo yum install -y lighttpd  

This will install lighttpd to the /etc/lighttpd/ folder. You can verify by running the 'find' command:

sudo find / -name lighttpd.conf  

Now skip to the Configure lighttpd section below.

Using cloud-init

For a slightly more advanced approach/shortcut you could also look at cloud-init to perform this install using the User Data field during instance creation:

#!/bin/bash
yum update -y  
yum install -y lighttpd  

Just as before, lighttpd will be installed in the /etc/lighttpd/ folder.

Now skip to the Configure lighttpd section below.

Using a Docker Container

Another alternative is to use lighttpd in a Docker container. To use Docker on EC2 Amazon Linux, launch an instance. If you intend to use EC2 Container Registry (ECR) to host this container, I recommend using a role assignment for the instance. You must assign the role during the creation of the instance. This makes it cleaner/easier to access ECR without having to install your access keys. This way, you can use the AWS CLI leveraging the role to perform the call according to the assigned permissions.

Below is the lighttpd dockerfile I use to create the container:

## Use Alpine Linux
FROM alpine

## Install lighttpd and remove install files
RUN apk add --update lighttpd \  
    && rm -rf /var/cache/apk/*

## Copy lighttpd config over to overwrite the config file
ADD lighttpd.conf /etc/lighttpd/lighttpd.conf

## Command on startup
CMD ["lighttpd", "-D", "-f", "/etc/lighttpd/lighttpd.conf"]  

For this docker container, I'm uploading a single lighttpd.conf. I collapsed included configs into a single conf file, with the edits from the Configure lighttpd section below. To build the container and tag it, simply run:

docker build -t lighttpd:latest .  

If you're using ECR, you get the instructions for tagging and pushing a container on startup. For the above, after granting Docker permissions to access ECR, it would simply be:

docker tag lighttpd:latest <container id>.dkr.ecr.<region>.amazonaws.com/<container>:<tag>  

Where the <> are replaced with the correct details.

When you log into the AWS instance, after installing Docker and logging into ECR, you simply perform a run command to have Docker retrieve/pull the container and run it:

docker run -p xxxx:xxxx --restart always -d <container id>.dkr.ecr.<region>.amazonaws.com/<container>:<tag>  

Where xxxx:xxxx is the port you're receiving requests on in that ec2 instance mapped to the server.port in the lighttpd.

Configure lighttpd

To configure lighttpd to perform redirects, you want to open the modules.conf file:

sudo vi /etc/lighttpd/modules.conf  

Modify the list of loaded modules to include rewrite and redirect by uncommenting those lines:

server.modules = (  
    "mod_access",
    #  "mod_alias",
    #  "mod_auth",
    #  "mod_evasive",
    "mod_redirect",
    "mod_rewrite",
    #  "mod_setenv",
    #  "mod_usertrack",
)

Save and exit the file (hitting the ESC key, and typing :wq!). Next, open the lighttpd.conf for writing:

sudo vi /etc/lighttpd/lighttpd.conf  

Scroll down to the Filename/File handling section. Simply add:

$HTTP["scheme"] == "http" {
    $HTTP["host"] =~ ".*" {
        url.redirect = (".*" => "https://www.domain.com")
    }
}    

This config will redirect all incoming requests to the new URL you set. Now you're ready to start redirecting HTTP to HTTPS. Thanks for checking us out.

Cover Photo by Nicholas A. Tonelli / CC BY 2.0

Jeremy Glesner
Virginia Website
Jeremy is a technology executive in the Washington DC area, and the lead engineer for Cork Hounds. Posting stories related to the technological underpinnings of Cork Hounds.