https 下 多级nginx 反向代理设置
一.问题以原因分析
1.在多级nginx 代理下进行https 配置。通常的架构是内部的nginx 之间采用的是http进行通讯,通常的架构配置如下:
一级代理配置https,二级以及以上的nginx 则是配置http。架构图如下:

2.配置https 最重要的两个参数为: proxy_redirect http:// $scheme://; proxy_set_header X-Forwarded-Proto $scheme; 第一个参数的作用是将请求重定向为指定的协议(http,https) 其中$scheme 是请求的nginx 的协议,即server 配置的是什么协议,则$scheme就是什么协议。 由于一级nginx 设置的是https 协议,所有$scheme 为https。这一级设置的协议就是我们浏览器中访问网站所采用的协议。 第二个参数的作用则是将请求结果中内容中的地址(css,js,图片等静态资源地址)重定向为访问的协议的地址。 例如:访问的域名为https://www.test.com 则返回结果将静态文件地址替换成https://www.test.com. 默认是http协议,如果不进行设置,会发现代理的网站的所有静态文件,图片,css,js等url 都是采用默认的http协议,导致https代理失败。 如果将以上的两个配置 proxy_redirect http:// $scheme://; proxy_set_header X-Forwarded-Proto $scheme; 设置在二级以及以上的反向代理中,将会导致整个网页的显示不正常。主要是由于二级以及以上的反向代理采用的是http协议,所以$scheme 始终都是http。错误的配置所导致的后果如下:
总而言之,在进行多级代理的时候。 一级代理中proxy_redirect 是决定原请求所采用的协议。 最下层的代理(nginx)将是决定网页中内容url 最终采用协议。 二.解决方案 针对这种情况将有3中方案来解决nginx https 的多级代理显示不正常的问题。 1.直接强制将最下级连接真正服务器的nginx 中的X-Forwarded-Proto 替换成https 如下配置 proxy_set_header X-Forwarded-Proto https; 通过这个方式,简单粗暴,但是通用性比较差,万一哪一天,我的一级代理使用的是http协议,则需要配套的修改最底层的配置来实现。 2.通过 X-Forwarded-Proto 来实现。 在nginx 中设置X-Forwarded-Proto 采用的协议,这个参数的值将会传递到下级的nginx 中。 通过$http_x_forwarded_proto 参数来进行获取。 则此时可以重新设置一个参数 $newscheme(这个自由定义只要不是$scheme即可) 设置如下 set $newscheme http; if ($http_x_forwarded_proto = 'https'){ set $newscheme https; } 之后在local 中配置则使用 proxy_set_header X-Forwarded-Proto $newscheme; 通过X-Forwarded-Proto 的传递性(在每一层的反向代理都需要这样配置),将最一级代理的协议一层一层的传递到最底层的反向代理中。 这个方案是通用性最强的一种解决方案,在每一层都可以这样设置 3.直接通过$http_x_forwarded_proto 来设置 proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; $http_x_forwarded_proto 这个变量值的初始化值是在第一层的方向代理通过proxy_set_header X-Forwarded-Proto $scheme; 设置出来的。 所以在第一层的代理,是不可以使用proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;进行协议的配置的。 这个适用二层或者以上的代理中。 通过以上配置就可以正常的使用网站。

浙公网安备 33010602011771号