How to redirect HTTP to HTTPS on AWS Application Load Balancer?

Our website needs HIPAA compliance so everything needs to be encrypted. I don't want client to get an error message when they put in "http://mysite.com", so I need to support both HTTP and HTTPS, and redirect HTTP to HTTPS. Am I right?

I did it correctly on the web servers. So if I directly connect to the web servers, HTTP is automatically redirected to HTTPS. All good.

But the web servers are sitting behind an AWS Application Load Balancer. I don't know how to redirect HTTP to HTTPS on the ELB. So client browsers can still connect to the ELB through HTTP.

How to set up HTTP => HTTPS on an AWS Application Load Balancer?

In other words, I am sure the connection between the ELB and web servers are HTTPS, but how to make sure the connection between the client browsers and the ELB are HTTPS?


Solution 1:

As of July 2018, this is supported on application load balancers.

  • Add/Edit your HTTP:80 listener
  • Set the action to Redirect
  • protocol: https
  • port: 443
  • set the next dropdown to Original host, path, query
  • set the last dropdown to 301 - Permanently moved

Image of settings for an HTTP to HTTPS listener on AWS application load balancer

Solution 2:

Usually what happens is that the ELB is set to receive https (port 443) and forward to EC2 instance (load balancer target) on http (port 80).

The backend web server redirects these requests to port 443 on the load balancer, causing an infinite loop of redirection (between the load balancer and the backend web server).

A common error message is ERR_TOO_MANY_REDIRECTS.

The solution is to look at the X-Forwarded-Proto, which is the protocol as seen by the load balancer, when deciding on redirection.

For nginx the config will look like this:

server {
    listen   80;
    server_name    www.example.org;   
    if ($http_x_forwarded_proto = 'http') {
         return 301 https://$server_name$request_uri;   
    }
}

and for apache .htaccess something like this:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

NOTE: Although one might think it would be convenient if this could be handled without webserver reconfiguration, as of spring 2018 there is no way of solving this using only ELB, i.e. you must configure your webserver to make this work.