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?

up vote 27 down vote accepted

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;
  • Unless I'm missing something, your before and after proxy_set_header lines are the same. – Wilfred Hughes Sep 26 '13 at 17:39
  • 1
    $scheme vs $thescheme. – Arlen Beiler Jul 2 '15 at 13:30
  • Isn't this in some rare cases insecure? If a web browser sends a HTTP request to haproxy, and haproxy then sends a HTTPS request to Nginx — then the default $scheme case will happen, setting $thescheme to HTTPS although in fact the request (to haproxy) is insecure HTTP. — To avoid that, what about: default $http_x_forwarded_proto; '' $scheme;, so if haproxy says HTTP it'll be respected. – KajMagnus May 8 at 14:28
  • That is suggested here: stackoverflow.com/a/21911864/694469 (i.e. default $http_x_forwarded_proto;). – KajMagnus May 8 at 14:41

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 ?

An other solution could be to use map as described here : http://redant.com.au/blog/manage-ssl-redirection-in-nginx-using-maps-and-save-the-universe/ but it's not exactly what I think you want to achieve, nope ??

  • Did you resolve your problem ? – Yannovitch Jun 15 '13 at 12:53
  • 1
    I figured it out. Your answer didn't help directly, but that second link helped me figure out a way to solve it. Thanks. – Echo Jun 17 '13 at 15:24

I had the same need with AWS ELB

Here is my solving line:

proxy_set_header        X-Forwarded-Proto $http_x_forwarded_proto;

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.