阿里云slb 7层代理ingress获取真实客户端ip的方法

本文介绍如何在Kubernetes中通过Ingress Nginx正确配置以获取客户端的真实IP地址,特别是当使用负载均衡器时,解决由于代理层导致的真实IP丢失问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

起因:ingress 设置ip白名单之后,发现白名单里的ip 403拒绝,后续通过追踪ingress的日志发现 真实的ip 是slb的保留ip 也就是上层代理的ip。这样是无法获取到真实用户的ip的。

nginx里的解决方案:

使用X-Forwarded-For的方式获取客户端的真实IP地址。

需要添加的配置字段和信息为:

set_real_ip_from IP_address

real_ip_header X-Forwarded-For;

ingress-nginx的配置方法如下:

kubectl edit cm nginx-configuration -n kube-system

新增:

http-snippet: |
set_real_ip_from 100.121.0.0/16;
real_ip_header X-Forwarded-For;

 

100.121.0.0 为slb的保留地址,每个slb的保留地址是不一样的,只要针对自己的slb保留地址做配置就好了。使用七层负载均衡默认情况下real_ip获取到的是slb的保留地址如以下日志:

{ "real_ip" : "100.121.134.220" ,"time": "2019-04-02T16:41:43+08:00", "remote_addr": "", "x-forward-for": "183.129.243.163, 100.121.134.220", "request_id": "3d55a0d610116e249d6fda1b4746d9b0", "remote_user": "-", "bytes_sent": 785, "request_time": 0.065, "status": 200, "vhost": "presboss.qjdchina.com", "request_proto": "HTTP/1.1", "path": "/clms/boss/accountbank/list", "request_query": "parentId=0", "request_length": 755, "duration": 0.065, "method": "GET", "http_referrer": "https://presboss.qjdchina.com/clms/boss/customerFlow/detail?taskId=1870002&processId=1867328", "http_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36" }

 

 

 

 

  • set_real_ip_from:真实服务器上一级代理的IP地址或者IP段,可以写多行
  • real_ip_header:从哪个header头检索出要的IP地址
  • real_ip_recursive:递归排除IP地址,ip串从右到左开始排除set_real_ip_from里面出现的IP,如果出现了未出现这些ip段的IP,那么这个IP将被认为是用户的IP。
    • 在real_ip_recursive on的情况下
      • 61.22.22.22,121.207.33.33,192.168.50.121都出现在set_real_ip_from中,仅仅120.22.11.11没出现,那么他就被认为是用户的ip地址,并且赋值到remote_addr变量
    • 在real_ip_recursive off或者不设置的情况下
      • 192.168.50.121出现在set_real_ip_from中,排除掉,接下来的ip地址便认为是用 户的 ip地址

    • 例如我上面的例子:
      • ​​​​​​183.129.243.163, 100.121.134.220 排除100.121.0.0/16网段的ip 剩下的183.129.243.163就是客户端的ip

》 注意

如果以上设置无法获取真实ip 那么需要检查下ingress svc的类型

这里我们要讲一下私有化案例:

场景在不使用阿里云的slb的前提

之前我一直以为ingress 只需要配置以上配置就可以获取到真实ip 不管那个场景,但是实际上不是的。以上成功案例是在loadblance模式下实现的。

那为什么loadblance可以nodeport 和 cluster就不可以呢?

这里我们来讲一下iptables svc的配置ExternalTrafficPolicy=Cluster

下这几种的区别

首先cluster模式从群集内发送到 ClusterIP 的数据包永远不会来自 DNAT,我们知道不经过dnat转换的ip是不可能出现在x-forward-for里的,所以你只能获取pod的IP

其次nodeport模式 nodeport模式实际就是snat,这里我们要了解到转换和转发的区别,转换是直接将源地址转换成目标地址,所以源地址将不会出现在ingress的x-forward-for里

为了避免这种情况,kubernetes可以修改ExternalTrafficPolicy为local(会将请求代理到本地端点,不将流量转发到其他节点,从而保留原始IP地址。如果没有本地端点,则丢弃发送到节点的数据包,因此您可以在任何数据包处理规则中依赖正确的客户端IP)

接着是loadblance,默认情况下,发送到具有 Type = LoadBalancer 的服务的数据包来源是 DNAT,因为该 Ready 状态中的所有可调度 Kubernetes 节点都能获得负载平衡流量。因此,如果数据包到达没有 endpoint 的 Node ,系统会将其代理到具有 endpoint 的 Node ,用这个 Node 的IP替换数据包上的源IP

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值