How to have nginx forward the HTTP_X_FORWARDED_PROTO header?

I'm chainging my setup from

nginx > apache/php

to

haproxy > nginx > apache/php

(using haproxy 1.5-dev18 with ssl support compiled in)

Both nginx and haproxy are setup correctly to set the HTTP_X_FORWARDED_PROTO header. However, when nginx gets the ssl traffic from haproxy, it sees the connection as http and sets the header as so.

How can I set nginx to forward the HTTP_X_FORWARDED_PROTO header if it exists, but otherwise continue setting it based on the connection?


Solution 1:

I figured out how to solve this. The problem was that nginx was overwriting the header set by haproxy on this line of my config:

proxy_set_header X-Forwarded-Proto $scheme;

I fixed it by adding in this:

map $http_x_forwarded_proto $thescheme {
     default $scheme;
     https https;
 }   

and changing the proxy_set_header line to use the new scheme:

proxy_set_header X-Forwarded-Proto $thescheme;

Solution 2:

I had the same need with AWS ELB

Here is my solving line:

proxy_set_header        X-Forwarded-Proto $http_x_forwarded_proto;

Solution 3:

I can't just comment so I post this as an answer : Could you give us part or all of your nginx configuration so we can see what's wrong with it ? Possibly your HAProxy config too ?

The first problem I can think of is that your HAProxy is doing ssl termination. To sum it up, to offload your backend servers, a load balancer can be configured to do all the ssl thing, and then communicate with your backend servers in HTTP. Like the scheme here : http://blog.exceliance.fr/2012/09/10/how-to-get-ssl-with-haproxy-getting-rid-of-stunnel-stud-nginx-or-pound/

To give you a good answer to your question, could you check you don't have any loopback problem in your http<>https config ? Maybe then you could redirect http to http, https to https, and then force http to be redirected to https.

Could you check too that you have enabled ssl passthrough in your HAProxy config ?