Currently I have an ELB serving both http://www.example.org and https://www.example.org.
I would like to set it up so any request pointing to http://www.example.org is redirect to https://www.example.org.
The ELB sends the https requests as http requests, so using:
server {
listen 80;
server_name www.example.org;
rewrite ^ https://$server_name$request_uri? permanent;
}
will not work because requests made to https://www.example.org will still be made to port 80 on nginx.
I know it's possible to rewrite it as
server {
listen 80;
server_name www.example.org;
if ($http_x_forwarded_proto != "https") {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
}
But everything I've read said that if
should be avoided at all costs within nginx configuration, and this would be for every single request. Also, it means I have to set up a special separate configuration for the health check (as described here: "…when you are behind an ELB, where the ELB is acting as the HTTPS endpoint and only sending HTTP traffic to your server, you break the ability to respond with an HTTP 200 OK response for the health check that the ELB needs").
I'm considering putting the login in the code of the web application rather than the nginx configuration (and for the purposes of this question let's assume it's a Django-based application), but I'm not certain whether that would be more overhead than the if
in configuration.
NGINX Setup
If it's working correctly like that, don't be scared of it. http://wiki.nginx.org/IfIsEvil
This solution uses conditional logic, but as the accepted answer suggests, I also think this is ok. Ref: https://stackoverflow.com/questions/4833238/nginx-conf-redirect-multiple-conditions
Also, this doesn't require opening any additional ports in the aws security settings for the image. You can terminate ssl in the AWS LB, and route https traffic to http port 80 on your instance.
In this example the LB health check hits /health on port 80 which routes to the app server, so the health check validates both nginx and your app are breathing.
You can now create a new Listener in AWS Load Balancer Settings which redirects HTTP Port 80 to HTTPS Port 443. So you don't need to touch the nginx/apache config anymore.