Linux 上的 nginx 1.7.9
问题:
当使用 nginx 时,Web 服务器将所有请求视为通过 http 发送,即使它们是通过 https 发送的。
使用 IIS 请求跟踪,我们可以看到请求是这样进入的,即使外部(来自浏览器)请求是这样的https://myapp.com:443/appdir/
:
RequestURL="http://myapp.com:80/appdir/"
但在我们的硬件负载均衡器(我们正在尝试逐步淘汰)上,它正确显示为:
RequestURL="https://myapp.com:443/appdir/"
应用程序需要查看 https,这取决于它。(它会尝试强制连接以确保安全。)
我们知道使用 X-Forwarded-Proto 之类的东西来告诉应用程序请求是通过 ssl 传入的,但是应用程序的一部分是围绕请求本身构建的,我们可能无法修改它。
硬件负载均衡器可以“完成所有工作” - 终止 SSL,并将看似对 https 的请求“伪装”发送回应用程序(通过端口 80)。
我如何让 nginx 将完整的、未改变的请求 url 传回服务器?
配置:
http {
upstream sandbox_site {
least_conn;
# we pipe to back end on port 80 only, so that nginx handles all ssl
server 192.168.2.16:80 max_fails=1 fail_timeout=60s; # sbox3-site is .2.16
}
server {
# This is sandbox.myapp.com block **************************************
listen 192.168.2.27:80;
server_name sandbox.myapp.com;
location / {
proxy_pass http://sandbox_site;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
# This is SSL version of sandbox.myapp.com block **************************************
listen 192.168.2.27:443 ssl;
server_name sandbox.myapp.com;
ssl_certificate new-sandbox-myapp-com.cer;
ssl_certificate_key new-sandbox-myapp-com.key;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://sandbox_site;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
答案1
基本上你有两个选择:
要么您正在卸载 SSL,就像您现在所做的那样,然后您可以告诉您的后端该请求实际上是通过 SSL 接收的(如果是的话):
proxy_set_header X-Forwarded-Proto $scheme;
但这肯定意味着您必须调整代码,以便处理该标题。
或者,如果不允许修改代码,您可以停止卸载 SSL,并通过它实际上从后端代理页面。
SSL 沙盒块看起来是这样的:
location / { proxy_pass https://sandbox_site; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
但是,第二种方式是多余的:您会看到,您实际上仍然卸载 SSL,但随后再次组装 SSL 请求,即使它来自您信任的网络。它所做的只是增加不必要的转换。