前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 Nginx real-ip 模块

使用 Nginx real-ip 模块

原创
作者头像
用户7365393
修改2021-09-24 14:18:14
1.8K0
修改2021-09-24 14:18:14
举报
文章被收录于专栏:人生得意须尽欢

使用 Nginx real-ip 模块获取,需在 Ingress 上配置 proxy-real-ip-cidr ,把WAF 和 SLB(7 层) 地址都加上。操作后服务端使用 X-Forwarded-For 可取到真实 IP,通过 X-Original-Forwarded-For 可取到伪造 IP。

这种方案有如下缺点:

•由于 WAF 是云厂商维护,WAF 地址池众多,同时地址会有变化,维护此动态配置难度极大,如更新不及时会导致获取的客户端 IP 不准确。•即使采用此方案,业务方如果要使用新版本的 Gin 的 ctx. ClientIP() 方法,仍然需改动代码,将所有可信代理配置到 TrustedProxies,这会导致基础设施和业务服务耦合,这种方案显然是无法接受的,除非业务方愿意将依赖的 Gin 版本锁死在 v1.6.3。

3.2.1.2. 使用 WAF 自定义 Header

不少云厂商提供了自定义 Header 来获取客户端真实 IP( $remote_addr )能力,我们可以在云厂商 WAF 终端中提前配置好自定义 Header 头,比如 X-Appengine-Remote-Addr 或 X-Client-Real-IP 等,用来获取客户端真实 IP。

这种方案有如下缺点:

•如直接复用 X-Appengine-Remote-Addr 这个 Header,则需设置 engine. AppEngine=true,才可通过 ctx. ClientIP() 方法的前提下获取客户端 IP。•如使用其他 Header,比如 X-Client-Real-IP,则需要自行封装从 X-Client-Real-IP 中获取客户端 IP 方法,同时需要业务配合做改造。

架构大概如下所示:

3.2.2. 客户端->CDN->WAF->SLB->Ingress->Pod
3.2.2.2. 使用 real-ip

使用 real-ip 模块获取,需要在 ingress 上配置 proxy-real-ip-cidr 把 CDN、WAF 和 SLB(7 层)的地址都加上,服务端使用 X-Forwarded-For 可取到真实 IP,通过 X-Original-Forwarded-For 可取到伪造 IP。

此方案优缺点:

•此场景相比 3.2.1 多了层 CDN,CDN 地址池比 WAF 更大,地址池变化频率更高,同时厂商也没有提供 CDN 地址池,维护 Ingress 配置基本不可能。•即使采用此方案,业务方如果要使用新版本的 Gin 的 ctx. ClientIP() 方法,仍然需改动代码,将所有可信代理配置到 TrustedProxies,这会导致基础设施和业务服务耦合,这个肯定无法接受,除非业务方将 Gin 版本锁死在 1.6.3。

3.2.2.1. 使用 CDN 自定义 Header

此方案优缺点:同 3.1.1。架构大概如下所示:

3.2.3. 客户端->SLB->Ingress->Pod

可通过 Ingress 上设置 use-forwarded-headers 来防止 X-Forwarded-For 伪造。

•use-forwarded-headers=false

适用于 Ingress 前无代理层,例如直接挂在 4 层 SLB 上,ingress 默认重写 X-Forwarded-For 为 $remote_addr ,可防止伪造 X-Forwarded-For 。

•use-forwarded-headers=true

适用于 Ingress 前有代理层,例如 7 层 SLB 或 WAF、CDN 等相当于在 nginx.conf 中添加如下配置:

代码语言:javascript
复制
real_ip_header      X-Forwarded-For; real_ip_recursive   on; set_real_ip_from    0.0.0.0/0; // 默认信任所有 IP,无法避免伪造 X-Forwarded-For

架构大概如下所示:

4. 总结

从上文中我们不难看出,在云上复杂多变的网络拓扑结构下,我们会频繁地维护 CDN、WAF、SLB、Ingress 等多种网络设施配置。如果需完全保证 X-Forwarded-For 不可伪造,对于要升级 Gin 框架的 Go 服务来说,只有如下两种方案:

•继续尝试通过 X-Forwarded-For 获取客户端真实 IP。•尝试通过其他 Header 获取客户端真实 IP。

4.1. 继续尝试通过 X-Forwarded-For 获取客户端真实 IP

业务中需配置基础设施所有前置代理到 TrustedProxies 中,包含 CDN 地址池、WAF 地址池、Kunernetest Nginx Ingress 地址池,这种方案基本无法落地:

•配置太过复杂,一旦获取 IP 不准,很难排查。•导致业务配置和基础设施耦合,基础设施如果对 CDN、WAF、Ingress 做变动,业务代码必须同步变更。•部分可信代理 IP 根本没法配置,比如 CDN 地址池。

4.2. 尝试通过自定义 Header 获取客户端真实 IP

基础设施团队提供自定义 Header 来获取客户端真实 IP,如 X-Client-Real-IP 或 X-Appengine-Remote-Addr 。这种方案需要基础设施团队在云厂商 CDN 或 WAF 终端上做好相应的配置。这种方案:

•配置简单可靠,维护成本低,仅需在 CDN、WAF 终端配置自定义 Header 即可。•如果使用 X-Appengine-Remote-Addr,对于使用 Google Cloud 的 App Engine 的服务不需做任何修改。对于使用的国内云厂商的服务,则需要显式的配置 engine. AppEngine = true,然后继续通过 ctx.ClientIP() 方法即可。•如果使用其他自定义 Header,如 X-Client-Real-IP 来获取客户端真实 IP,建议可以考虑自行封装 ClientIP(*gin.Context) string 函数,从 X-Client-Real-IP 中获取客户端 IP。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3.2.1.2. 使用 WAF 自定义 Header
  • 3.2.2. 客户端->CDN->WAF->SLB->Ingress->Pod
  • 3.2.2.2. 使用 real-ip
  • 3.2.2.1. 使用 CDN 自定义 Header
  • 3.2.3. 客户端->SLB->Ingress->Pod
  • 4. 总结
    • 4.1. 继续尝试通过 X-Forwarded-For 获取客户端真实 IP
      • 4.2. 尝试通过自定义 Header 获取客户端真实 IP
      相关产品与服务
      内容分发网络 CDN
      内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档