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

2021/8/30 7:06:12

本文主要是介绍k8s中ingress以及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



这篇关于k8s中ingress以及nginx获取客户端真实IP的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程