lon*_*nix 51 reverse-proxy http nginx http-headers nginx-reverse-proxy
我使用 Nginx 作为反向代理。
这些标头有什么区别:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
Run Code Online (Sandbox Code Playgroud)
在一些文档/教程中,我看到两者都被使用,而在其他文档/教程中,只有第一个。
它们看起来很相似,所以我想了解它们有何不同以及我是否需要同时使用两者。
Iva*_*sky 63
这些标头有什么区别?
您检查了$proxy_add_x_forwarded_for变量文档吗?
客户
X-Forwarded-For端请求标头字段及其$remote_addr附加的变量,以逗号分隔。如果X-Forwarded-For客户端请求标头中不存在该字段,则该$proxy_add_x_forwarded_for变量等于该$remote_addr变量。
如果传入请求已经包含X-Forwarded-For标头,可以说
X-Forwarded-For: 203.0.113.195, 150.172.238.178
Run Code Online (Sandbox Code Playgroud)
并且您的请求来自 IP 198.51.100.17,新的X-Forwarded-For标头值(要传递到上游)将是
X-Forwarded-For: 203.0.113.195, 150.172.238.178, 198.51.100.17
Run Code Online (Sandbox Code Playgroud)
如果传入请求不包含X-Forwarded-For标头,则该标头将传递给上游,如下所示
X-Forwarded-For: 198.51.100.17
Run Code Online (Sandbox Code Playgroud)
另一方面,按照X-Real-IP您在问题中显示的方式设置的标头将始终等于$remote_addrnginx 内部变量,在这种情况下它将是
X-Real-IP: 198.51.100.17
Run Code Online (Sandbox Code Playgroud)
(除非ngx_http_realip_module将参与将该变量值更改为实际远程对等地址之外的其他值;阅读模块文档以查找所有详细信息;这个SO 问题也有一些有用的示例/其他详细信息。)
我是否需要同时使用两者?
您的第一个问题应该是“我是否需要将这些标头添加到发送到后端的请求中?” 这实际上取决于您的后端应用程序。它依赖于这些标头中的任何一个吗?这些标头值实际上会对应用程序行为产生任何影响吗?您的后端应用程序如何处理这些标头值?正如您所看到的,请求来源假定为X-Forwarded-For地址列表中的第一个地址。另一方面,该标头很容易被欺骗,因此某些服务器设置可能允许仅将该标头用于受信任的源,否则将其删除。如果您X-Real-IP通过服务器设置设置标头,它将始终包含实际的远程对等地址;如果您不这样做,并且您收到了一个带有X-Real-IP标头的欺骗请求,它将按原样传递到您的后端,如果您的应用程序更愿意依赖该标头而不是X-Forwarded-For一个标头,这可能会非常糟糕。不同的后端应用程序可能表现不同;你可以查看这个GitHub 问题讨论来了解这个想法。
总结一下这一切。
如果您确实知道后端应用程序实际可以处理哪些标头以及如何完成,则应根据处理方式设置必需的标头并跳过非必需的标头,以最大程度地减少代理负载。如果您不这样做,并且您不知道您的应用程序是否会被错误的X-Forwarded-For标头欺骗,并且您的 nginx 实例前面没有受信任的代理服务器,那么最安全的方法是根据实际的远程对等地址设置两者:
X-Forwarded-For: 203.0.113.195, 150.172.238.178
Run Code Online (Sandbox Code Playgroud)
如果您确定您的后端应用程序不会被错误的X-Forwarded-ForHTTP 标头欺骗,并且您想向其提供原始请求中获得的所有信息,请使用您在问题中显示的示例:
X-Forwarded-For: 203.0.113.195, 150.172.238.178, 198.51.100.17
Run Code Online (Sandbox Code Playgroud)
一些附加的技术信息。
实际上,这些X-Forwarded-...HTTP 标头是某种非标准标头。根据 MDN,假设用于传输此类信息的标准标头将在RFC7230Via中描述,并且在RFC7239中描述。然而, ,和成为替代和事实上的标准版本而不是那些。更可靠的方法是使用以下任一方法显式设置代理请求的 HTTP 标头,而不是使用后端应用程序可能会或可能不会解释的 。ForwardedX-Forwarded-ForX-Forwarded-HostX-Forwarded-ProtoX-Forwarded-HostHost
X-Forwarded-For: 198.51.100.17
Run Code Online (Sandbox Code Playgroud)
或者
X-Real-IP: 198.51.100.17
Run Code Online (Sandbox Code Playgroud)
甚至
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
Run Code Online (Sandbox Code Playgroud)
(您可以在此处$host检查、$http_host和$server_namenginx 内部变量之间的区别。)另一方面,经常用于告诉后端应用程序原始请求是否是通过加密的 HTTPS 协议发出的。有时您甚至可以看到配置中使用的标头;对我来说,这看起来毫无意义,因为后端应用程序的行为不应根据您实际使用的反向代理软件而有所不同;但是我相信有一些网络应用程序确实可以以某种有用的方式处理这个问题。MDN根本没有提到header;然而,该应用程序应该提供相当多的网络应用程序。X-Forwarded-ProtoX-Forwarded-ProxyX-Real-IP
还有一个技术细节。与其他一些反向代理服务器一样,nginx 会将多个X-Forwarded-For标头“折叠”为一个标头,因此
proxy_set_header X-Forwarded-For $proxy_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
Run Code Online (Sandbox Code Playgroud)
和
proxy_set_header Host $host;
Run Code Online (Sandbox Code Playgroud)
配置片段的行为相同,将单个X-Forwarded-For标头传递到后端应用程序,无论使用什么配置,都是相同的。
| 归档时间: |
|
| 查看次数: |
47810 次 |
| 最近记录: |