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

网友投稿 653 2022-09-01

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官方文档: 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 配置

#放在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使用以上的配置就可以了

作者:​​小家电维修​​

转世燕还故榻,为你衔来二月的花。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:KMP训练五题
下一篇:Python数据分析之pandas学习(二)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~