如何让nginx转发HTTP_X_FORWARDED_PROTO头部?

我正在改变我的设置从
nginx > apache/php

haproxy > nginx > apache/php
(使用已编译支持SSL的haproxy 1.5-dev18) nginx和haproxy都已正确设置HTTP_X_FORWARDED_PROTO头部。然而,当nginx从haproxy接收到SSL流量时,它将连接视为http,并相应地设置头部。 如果存在HTTP_X_FORWARDED_PROTO头部,我该如何设置nginx来转发它,否则继续根据连接设置头部?
3个回答

我找到了解决方法。问题是nginx在我的配置文件的这一行上覆盖了haproxy设置的标头。
proxy_set_header X-Forwarded-Proto $scheme;
我通过添加以下内容来修复它:
map $http_x_forwarded_proto $thescheme {
     default $scheme;
     https https;
 }   
将代理设置头行更改为使用新方案:
proxy_set_header X-Forwarded-Proto $thescheme;

除非我漏掉了什么,你的proxy_set_header前后的行是一样的。 - Wilfred Hughes
2$scheme$thescheme的区别。 - Arlen Beiler
1这在某些罕见情况下不安全吗?如果一个网络浏览器向haproxy发送HTTP请求,然后haproxy再向Nginx发送HTTPS请求 - 那么default $scheme的情况将发生,将$thescheme设置为HTTPS,尽管实际上(对于haproxy)的请求是不安全的HTTP。- 为了避免这种情况,怎么样考虑一下:default $http_x_forwarded_proto; '' $scheme;,这样如果haproxy说是HTTP,就会被尊重。 - KajMagnus
这里建议使用:https://stackoverflow.com/a/21911864/694469(即`default $http_x_forwarded_proto;`)。 - KajMagnus
看起来你是在强制发送安全请求。 - Kiran

我也有同样的需求,关于AWS ELB

以下是我的解决方案:

proxy_set_header        X-Forwarded-Proto $http_x_forwarded_proto;

我应该在哪里设置$http_x_forwarded_proto?那是什么意思? - Jonathan
$http_x_forwarded_proto 是 NGINX 的实现。 - jobwat
2你的回答刚好解决了我三天来一直苦苦思索的问题!关于AWS负载均衡器和HTTPS的主题,其他帖子都推荐使用proxy_set_header X-Forwarded-Proto $scheme;,但实际上并不起作用。 - MikeMarsian
$http_x_forwarded_proto是nginx暴露X-Forwarded-Proto头的方式。在http://nginx.org/en/docs/http/ngx_http_core_module.html#variables中查看"$http_name"的文档。 - RobSiklos
这个是不是只是从上游请求中复制头部的值?难道nginx不应该自动处理这个吗? - Migwell
我在我的设置中使用了proxy_set_header x-forwarded-proto https;,最终它起作用了。我的设置是与node.js作为上游一起使用的。 - myNewAccount
当我这样做时,我的应用程序会得到X-Forwarded-Proto=http,https - Luciano

我不能只评论,所以我把这个作为一个答案发出来:你能给我们提供部分或全部的nginx配置吗?这样我们就可以看出问题出在哪里了。如果可能的话,也请提供你的HAProxy配置。 我能想到的第一个问题是你的HAProxy正在进行SSL终止。简而言之,为了卸载后端服务器的负载,负载均衡器可以配置为处理所有的SSL事务,然后通过HTTP与后端服务器通信。就像这里的方案一样:http://blog.exceliance.fr/2012/09/10/how-to-get-ssl-with-haproxy-getting-rid-of-stunnel-stud-nginx-or-pound/ 为了给你一个好的答案,你能检查一下你的http<>https配置中是否有任何回环问题吗?也许你可以将http重定向到http,https重定向到https,然后强制将http重定向到https。 你还能检查一下你的HAProxy配置中是否启用了ssl passthrough吗?

你解决了问题吗? - Yannovitch
1我搞定了。你的回答并没有直接帮助我,但是第二个链接帮助我找到了解决方法。谢谢。 - Echo says Reinstate Monica