nginx X-Forwarded-For和X-Real-IP标头之间的差异

vq8itlhq  于 2022-12-03  发布在  Nginx
关注(0)|答案(1)|浏览(177)

我使用Nginx作为反向代理。
这些标题之间的区别是什么:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP       $remote_addr;

在一些文档/教程中,我看到两者都使用,在其他文档/教程中只使用第一个。
它们看起来很相似,所以我想了解它们有什么不同,以及我是否需要同时使用这两种方法。

q3aa0525

q3aa05251#

这些标题之间有什么区别?
是否查看了$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

并且您的请求来自IP 198.51.100.17,则新的X-Forwarded-For报头值(将传递到上游)将是

X-Forwarded-For: 203.0.113.195, 150.172.238.178, 198.51.100.17

如果传入的请求不包含X-Forwarded-For标头,则此标头将作为

X-Forwarded-For: 198.51.100.17

另一方面,按照您在问题中显示的方式设置的X-Real-IP头将始终等于$remote_addr nginx内部变量,在本例中为

X-Real-IP: 198.51.100.17

(除非X1 E0 F1 X将涉及将该变量值改变为除实际远程对等体地址之外的某个值;阅读模块文档以了解所有详细信息; this SO问题也有一些有用的示例/其他详细信息。)
我是否需要同时使用两者?
你的第一个问题应该是“我是否需要将这些头添加到发送到我的后端的请求中?”这实际上取决于你的后端应用程序。它是否依赖这些头?这些头的值实际上对应用程序的行为有什么影响吗?你的后端应用程序如何处理这些头的值?正如你所看到的,另一方面,该报头很容易被欺骗,因此某些服务器设置可能只允许将该报头用于可信源,如果您通过服务器设置设置了X-Real-IP头,它将始终包含实际的远程对等地址;如果你不这样做,并且你得到了一个欺骗的请求,其中已经存在X-Real-IP头,它将被原样传递到你的后端,如果你的应用更喜欢依赖该头而不是X-Forwarded-For头,这可能真的很糟糕。您可以查看this GitHub问题讨论来了解这个想法。
"总结这一切"
如果你明确知道你的后端应用程序实际上可以处理哪些头文件以及如何处理,你应该根据它们的处理方式设置必需的头文件,而跳过非必需的头文件,以最大限度地减少代理的有效负载。如果你不知道,你不知道你的应用程序是否会被不正确的X-Forwarded-For头文件欺骗,而且你没有受信任的代理服务器(s)在你的nginx示例前面,最安全的方法将是根据一个实际的远程对等地址设置这两个:

proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP       $remote_addr;

如果您确信您的后端应用不会被错误的X-Forwarded-For HTTP头欺骗,并且您希望向其提供原始请求中的所有信息,请使用问题中显示的示例:

proxy_set_header X-Forwarded-For $proxy_x_forwarded_for;
proxy_set_header X-Real-IP       $remote_addr;

一些其他技术信息。

实际上,那些X-Forwarded-... HTTP头是某种非标准头。根据MDN,假设用于传输此类信息的标准头是RFC 7230中描述的Via和RFC 7239中描述的Forwarded。然而,X-Forwarded-ForX-Forwarded-HostX-Forwarded-Proto成为了替代和事实上的标准版本,而不是使用X-Forwarded-Host,这可能会或可能不会被您的后端应用解释,一种更可靠的方法是使用以下方法之一为代理请求显式设置Host HTTP报头

proxy_set_header Host $host;

proxy_set_header Host $http_host;

或者甚至

proxy_set_header Host $server_name;

(you我可以检查$host$http_host$server_name nginx内部变量here之间的区别。)另一方面,X-Forwarded-Proto经常用来告诉后端应用程序原始请求是否是通过加密的HTTPS协议发出的。至于我,这一个看起来毫无意义,因为后端应用程序不应该表现不同,取决于反向代理软件,你实际使用;但是我相信有一些Web应用程序确实可以用某种有用的方式来处理这个问题。然而,那肯定是相当多的网络应用程序,应该提供与那一个。
与其他反向代理服务器一样,nginx会将多个X-Forwarded-For头“折叠”成一个头,因此

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_set_header X-Forwarded-For $remote_addr;

配置片段的行为将完全相同,将单个X-Forwarded-For头传递到后端应用,无论使用什么配置,都是相同的。

相关问题