ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

k8s中ingress以及nginx获取客户端真实IP

2021-08-29 23:34:20  阅读:210  来源: 互联网

标签:ingress Forwarded ip nginx IP 客户端


 

1.背景信息

  公司游戏官网的项目,集群使用ingress开放出去,后端由于是php语言编写,所以在php的pod里面也需要一个nginx来开放连接。所以本次的路由顺序就如以下:

      腾讯云LB → ingress → nginx

  所以本次环境,ingress和nginx都需要获取客户端的真实IP。所以本篇文档还是主要讲解一下使用方式和注意事项。

 

2.基本概念

  以上讲解了ingress和nginx获取真实IP的方式,这里还是简单的了解一下基本概念。

 

  (1)remote_addr

  代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的

  当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)

  就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站

  这样web服务器就会把remote_addr设为这台代理机器的IP,除非代理将你的IP附在请求header中一起转交给web服务器

 

  (2)X-Forwarded-For(简称XFF)

  X-Forwarded-For 是一个 HTTP 扩展头部,HTTP协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入

  用来表示 HTTP 请求端真实 IP,如今它已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用

  并被写入 RFC 7239(Forwarded HTTP Extension)标准之中

  XFF的格式为X-Forwarded-For: client, proxy1, proxy2

 

  XFF 的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP,然后是每一级代理设备的 IP

  (注意:如果未经严格处理,可以被伪造)

  如果一个 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 字段获得

 

  (3)X-Real-IP

  这又是一个自定义头部字段,通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP

  这个设备可能是其他代理,也可能是真正的请求端,这个要看经过代理的层级次数或是是否始终将真实IP一路传下来

  (注意:如果未经严格处理,可以被伪造)

 

3.Ingress 获取客户端真实IP

  通常,用户ip的传递依靠的是X-Forwarded-*参数。但是默认情况下,ingress是没有开启的。

  ingress的文档还比较详细,这里介绍一下可能用到的这3个参数:

  ingress官方文档: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#use-forwarded-headers

  以上有三个比较重要的参数。下面一一解释

 

3.1 use-forwarded-headers

  • 如果Nginx在其他7层代理或负载均衡后面,当期望Nginx将X-Forwarded-*的头信息传递给后端服务时,则需要将此参数设为true
  • 如果设为false(默认为false),Nginx会忽略掉X-Forwarded-*的头信息。false设置适用于Nginx直接对外或前面只有3层负载均衡的场景

  由于ingress的主配置是从configmap中获取的,更新参数则需要修改名为nginx-configuration的configmap的配置:在data配置块下添加use-forwarded-headers: "true"

  修改后,ingress nginx会自动加载更新nginx.conf主配置文件。下图为更新前后配置文件变化对比:

  注意:左边为开启use-forwarded-headers后ingress nginx主配置文件,右边为开启前

 

3.2 forwarded-for-header

  用来设置识别客户端来源真实ip的字段,默认是X-Forwarded-For。如果想修改为自定义的字段名,则可以在configmap的data配置块下添加:forwarded-for-header: "THE_NAME_YOU_WANT"。通常情况下,我们使用默认的字段名就满足需求,所以不用对这个字段进行额外配置。当然,你想显示的配置也可以。

 

3.3 compute-full-forwarded-for

  如果只是开启了use-forwarded-headers: "true"的话,会发现还是没能获取到客户端来源的真实ip,原因是当前X-Forwarded-For变量是从remote_addr获取的值,每次取到的都是最近一层代理的ip。为了解决这个问题,就要配置compute-full-forwarded-for字段了,即在configmap的data配置块添加:compute-full-forwarded-for: "true"。其作用就是,将客户端用户访问所经过的代理ip按逗号连接的列表形式记录下来。

  待ingress nginx加载configmap并更新主配置文件后,对比更新前后变化如下:

  注:左边是未开启compute-full-forwarded-for配置的ingress nginx主配置文件,右边是开启了的

 

3.4 举例说明

  如果从客户端ip0发起一个HTTP请求到达服务器之前,经过了三个代理proxy1、proxy2、proxy3,对应的ip分别为ip1、ip2、ip3,那么服务端最后得到的X-Forwarded-For值为:ip0,ip1,ip2。列表中并没有ip3,ip3可以在服务端通过remote_addr来获得。这样应用程序通过获取X-Forwarded-For字段的第一个ip,就可以得到客户端用户真实ip了。

 

3.5 注意项

  值得注意的是,并不是所有的场景都能通过X-Forwarded-For来获取用户正式ip。

  比如,当服务器前端使用了CDN的时候,X-Forwarded-For方式获取到的可能就是CDN的来源ip了,

  这种情况,可以根CDN厂商约定一个字段名来记录用户真实ip,然后代理将这个字段逐层传递,最后到服务端。

 

4.Nginx获取客户端真实IP

  先讲解ingress在讲解nginx原因是因为,在架构图里面,nginx在ingress后面,这里有一个非常需要注意的点就是,如果ingress不先拿到客户端的真实IP,nginx不管怎么配置都拿不到,因为在ingress那一层就没有真实的客户端IP了。往后面nginx传递的也就没有真实IP了。

 

4.1 配置

#放在http模块等,个人比较喜欢放在http

set_real_ip_from 192.168.1.0/24; #真实服务器上一级代理的IP地址或者IP段,可以写多行。 

real_ip_header   X-Forwarded-For;  #从哪个header头检索出所要的IP地址。

real_ip_recursive on;      #递归的去除所配置中的可信IP。排除set_real_ip_from里面出现的IP。如果出现了未出现这些IP段的IP,那么这个IP将被认为是用户的IP。

  Nginx使用以上的配置就可以了

 

参考:https://www.cnblogs.com/yudai/p/10974444.html

标签:ingress,Forwarded,ip,nginx,IP,客户端
来源: https://www.cnblogs.com/lizexiong/p/15204071.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有