[collect]HTTP头中x-Forwarded-For、x-Real-IP、remote_addr这几者之间的区别


=Start=

缘由:

之前有过简单了解HTTP头中这几个字段的作用,平时也能说个一二,但是细节可能就没那么清楚了,这次在代码中遇到了,趁着这个机会总结整理一下,方便以后参考。

正文:

参考解答:

X-Forwarded-For, X-Real-IP, remote_addr是HTTP协议中用来表示客户端地址的请求头。

X-Forwarded-For和X-Real-IP只有请求存在代理时才有值,而remote_addr一直存在。

  • X-Forwarded-For:记录代理服务器的地址,每经过一个代理,该字段会追加上一个记录。格式形如:1.1.1.1, 2.2.2.2。
  • X-Real-IP:也是用来记录服务器的地址,但是和上面的不同,它不把记录添加到结尾,而是直接替换
  • remote_addr:上一个客户端连接的地址,不存在代理就表示客户端的地址,存在代理就表示最后一个代理服务器的地址。

如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,那么按照 XFF 标准,服务端最终会收到以下信息:

X-Forwarded-For: IP0, IP1, IP2

Proxy3 直连服务器,它会给 XFF 追加 IP2,表示它是在帮 Proxy2 转发请求。列表中并没有 IP3,IP3 可以在服务端通过 Remote Address 字段获得。我们知道 HTTP 连接基于 TCP 连接,HTTP 协议中没有 IP 的概念,Remote Address 来自 TCP 连接,表示与服务端建立 TCP 连接的设备 IP,在这个例子里就是 IP3。

Remote Address 无法伪造,因为建立 TCP 连接需要三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求。不同语言获取 Remote Address 的方式不一样,例如 php 是 $_SERVER[“REMOTE_ADDR”],Node.js 是 req.connection.remoteAddress,但原理都一样。

X-Real-IP 通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP,这个设备可能是其他代理,也可能是真正的请求端。需要注意的是,X-Real-IP 目前并不属于任何标准,代理和 Web 应用之间可以约定用任何自定义头来传递这个信息。

proxy_set_header X-Real-IP $remote_addr; # 无法为真正使用代理的用户提供更好的服务(覆盖,请求到达 Nginx 之前的所有代理信息都被最后一个覆盖掉)

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 更常用(叠加)

结论:

1、直接对外提供服务的 Web 应用,在进行与安全有关的操作时,只能通过 Remote Address 获取 IP,不能相信任何请求头;
2、使用 Nginx 等 Web Server 进行反向代理的 Web 应用,在配置正确的前提下,要用 X-Forwarded-For 最后一节 或 X-Real-IP 来获取 IP(因为 Remote Address 得到的是 Nginx 所在服务器的内网 IP);同时还应该禁止 Web 应用直接对外提供服务;
3、在与安全无关的场景,例如通过 IP 显示所在地天气,可以从 X-Forwarded-For 靠前的位置获取 IP,但是需要校验 IP 格式合法性;


一般来说,X-Forwarded-For是用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP「追加」在X-Forwarded-For中。

假设来自4.4.4.4的一个请求,header包含这样一行:
X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3

说明请求由 1.1.1.1 发出,经过三层代理,第一层是 2.2.2.2 ,第二层是 3.3.3.3 ,而本次请求的来源IP 4.4.4.4 是第三层代理。

对于X-Real-IP,没有相关标准,上面的例子,如果配置了X-Read-IP,可能会有两种情况

// 最后一跳是正向代理,可能会保留真实客户端IP
X-Real-IP: 1.1.1.1
// 最后一跳是反向代理,比如Nginx,一般会是与之直接连接的客户端IP
X-Real-IP: 3.3.3.3

所以 ,如果只有一层代理,这两个头的值就是一样的。

 

参考链接:

=END=


《 “[collect]HTTP头中x-Forwarded-For、x-Real-IP、remote_addr这几者之间的区别” 》 有 8 条评论

  1. 寻找CloudFlare和TOR背后的真实源IP
    https://xz.aliyun.com/t/2781
    https://www.secjuice.com/finding-real-ips-of-origin-servers-behind-cloudflare-or-tor/
    `
    本文对隐藏了IP的服务器寻找真实源IP提供了一些思路和方法,工具主要使用 Censys[https://censys.io/]

    1 SSL证书
    1.1 使用给定的域名
    1.2 使用给定的SSL证书
    2. DNS 记录
    3. HTTP头
    4. 应用及服务
    5. 内容
    `
    https://en.wikipedia.org/wiki/Tor_(anonymity_network)#Hidden_services
    https://support.dnsimple.com/articles/a-record/
    http://www.chinaz.com/web/2015/0121/379846.shtml
    https://zhidao.baidu.com/question/1691539939903827828.html

  2. 用于保护 Web 服务的基本 HTTP 头介绍
    https://pentest-tools.com/blog/essential-http-security-headers/
    `
    Server headers that protect against attacks
      HTTP Strict Transport Security
      Content Security Policy
      Access-Control-Allow-Origin
      X-FrameOptions
      X-XSS-Protection
      X-Content-Type-Options
    Server headers that leak information
      Server
      X-Powered-By
      X-AspNet-Version
    `

  3. 完整的Web服务日志字段
    https://bloodzer0.github.io/ossa/infrastructure-security/host-security/log-analysis/get-ip/
    `
    nginx日志字段
    默认日志字段
    其它可使用字段
    nginx透传客户端真实IP
    – 使用X-Forwarded-For + realip模块
    – 使用X-Forwarded-For + 安全设置
    – 使用X-Real-IP
    参考资料
    `
    Nginx多级反向代理下的IP透传
    https://www.cnblogs.com/tea-melon/p/10977516.html

    Nginx 之 X-Forwarded-For 中首个IP一定真实吗?
    https://chenyongjun.vip/articles/78

  4. 日志分析系列(外传一):Nginx透过代理获取真实客户端IP
    https://mp.weixin.qq.com/s/Z0d8G7S5swBcH-jLXvhKeg

    阿里云 如何获取客户端真实IP
    https://help.aliyun.com/document_detail/54007.html

    使用知道创宇云安全后如何获取访客真实IP
    http://help.yunaq.com/faq/67/index.html

    Nginx多级反向代理下的IP透传
    https://www.cnblogs.com/tea-melon/p/10977516.html

    Nginx之X-Forwarded-For中首个IP一定真实吗?
    https://juejin.im/entry/5bbb6e90f265da0a89304a43

  5. 如何隐藏你的真实ip
    https://mp.weixin.qq.com/s/ORqYAyAcIX4ckTs1aiaf1Q
    `
    # 下面这个讨论主要是基于通过浏览器访问服务的时候,在提供服务的页面插入WebRTC的script代码用以获取真实IP,在服务面对的人群比较小众,且不太用考虑隐私协议的时候是没问题的,但是对于一些大厂而言,因为各种各样的原因,类似js代码注入可能不能那么普遍。所以配置好nginx拿到正常情况下能拿到的IP就行了。
    而且退一步说就算拿到的是你用了代理之后的IP,也可以用其它维度的数据和操作来识别出有问题的账号和设备。

    ==
    1. ip查看

    前段时间看到有大佬发了一篇文章:什么!我用代理你还可以找到真实ip?

    感觉很有意思,总结下来就是在使用隧道技术的情况下,哪怕是全局,依旧能够访问到你的真实ip。

    这里用到的技术主要是WEBRTC(需要浏览器支持)。

    2. 屏蔽方法

    2.1 Firefox浏览器
    插件名称:Disable WebRTC,允许该插件在隐私模式下使用

    2.2 Chrome浏览器
    Chrome浏览器插件:WebRTC Leak Prevent

    ==
    STUN(Simple Traversal of UDP over NATs,NAT的UDP简单穿越)是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一 个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT 路由器之后的主机之间建立UDP通信。该协议由RFC 3489定义。

    Firefox 跟 Chrome支持WebRTC可以向STUN服务器请求,返回内外网IP,不同于XMLHttpRequest请求,STUN请求开发者工具当中看不到网络请求的Firefox 跟 Chrome支持WebRTC可以向STUN服务器请求,返回内外网IP,不同于XMLHttpRequest请求,STUN请求开发者工具当中看不到网络请求的!
    `

  6. WebRTC泄露源IP的防范措施
    https://mp.weixin.qq.com/s/A5dd7WXojGBzsz52_iLtJQ
    https://scz.617.cn/web/202304131224.txt
    https://weibo.com/2635351511/MBMlNlhNq
    `
    目录:
    ☆ 背景介绍
    ☆ 测试WebRTC泄露源IP
    ☆ 阻止WebRTC泄露源IP
    1) WebRTC Leak Shield (推荐)
    2) 其他扩展
    3) 其他讨论
    ☆ 后记
    `
    最初看到「安全北北」的分享,将信将疑。接完cby回家,赶紧在Win10上测试,Chrome/Opera/Edge不幸中招,Firefox逃过此劫,我没有其他浏览器,据说Safari在此问题上表现不错。测试方案很简单,打开浏览器,挂线路访问如下URL
    https://ip8.com/webrtc-test

    社会可能毒打你。看到A、B机IP同时出现在C机页面上,内心是崩溃的,颠覆了我本就不多的WEB安全认知,无知者无畏太可怕。另一个中文测试URL
    https://www.hackjie.com/tracking

    WebRTC Leak Shield 扩展附送了一个DNS泄露测试URL
    https://dnsleaktest.org/dns-leak-test

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注