Redirecting EC2 Elastic Load Balancer from HTTP to HTTPS
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.
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.