Redirecting EC2 Elastic Load Balancer from HTTP to HTTPS
AWS Application Load Balancers now support native HTTP to HTTPS redirect.
To enable this in the console, do the the following:
- Go to your Load Balancer in EC2 and tab "Listeners"
- Select "View/edit rules" on your HTTP listener
- Delete all rules except for the default one (bottom)
- Edit default rule: choose "Redirect to" as an action, leave everything as default and enter "443" as a port.
The same can be achieved by using the CLI as described here.
It is also possible to do this in Cloudformation, where you need to set up a Listener object like this:
HttpListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !Ref LoadBalancer Port: 80 Protocol: HTTP DefaultActions: - Type: redirect RedirectConfig: Protocol: HTTPS StatusCode: HTTP_301 Port: 443
If you still use Classic Load Balancers, go with one of the NGINX configs described by the others.
ELB sets X-Forwarded-Proto
header, you can use it to detect if original request was to HTTP and redirect to HTTPS then.
You can try this in your server
conf:
if ($http_x_forwarded_proto = 'http') { return 301 https://yourdomain.com$request_uri;}
Take a look at ELB docs.
I had the same problem, in my situation HTTPS was handled entirely by ELB and I didn't know my source domain ahead of time so I ended up doing something like:
server { listen 81; return 301 https://$host$request_uri;}server { listen 80; # regular server rules ...}
And then of course pointing the ELB 'https' to the instance port 80 and then the 'http' route to the instance port 81.