使用 istio 后如何获取客户端真实 IP

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 istio 后如何获取客户端真实 IP相关的知识,希望对你有一定的参考价值。

参考技术A 使用 istio 为工作负载注入 sidecar 后,envoy 会代理工作负载的所有网络请求,导致工作负载收到的流量来自 envoy 的转发,因此工作负载看到的客户端 IP 是 envoy 的,默认是 127.0.0.6 ,不是真实的客户端地址。

某些 app 是需要获取到真实客户端地址的,比如黑白名单、地理位置判断等等。

早期的 istio 版本是比较难解决的,但新版本中已经很容易解决,本文中的 istio 是 1.11.2 版本,只需要使用下面的 HTTP Header 即可获取到客户端真实的 IP 地址:

两个的区别是, $http_x_original_forwarded_for 会包含所有中间代理的地址,而

$http_remoteip 仅包含最近一个代理的地址。

举个例子:当工作负载前方有 CDN、WAF、SLB 等代理时, $http_x_original_forwarded_for 会包含这些代理的所有地址,逐个从左到右增加到列表中。而 $http_remoteip 仅包含最近的一个代理地址,即 SLB 的地址。

但正常情况下,真实的客户端 IP 是在最前端的,即应该在 $http_x_original_forwarded_for 的左边第一位,所以还需要做处理,可参考下面的方式进行处理:

$clientRealIp 将是真实的客户端 ip 地址。

通过下面的命令,虚拟 3 个 ip 到 X-Forwarded-For 中进行测试

可以看到 nginx 日志中将打印最前面的 56.5.6.7 的 ip 地址

如果本机直接访问页面,将打印本机的公网 ip 地址,如下图:

在 k3s 上使用 Traefik 时如何获取客户端的真实 IP 地址?

【中文标题】在 k3s 上使用 Traefik 时如何获取客户端的真实 IP 地址?【英文标题】:How can I get the real ip address of a client when using Traefik on k3s? 【发布时间】:2021-06-16 19:19:44 【问题描述】:

我浏览了许多博客文章和 SO 问题以及 k3s 文档,但仍然无法获得客户端的真实 IP 地址,而不是内部集群 IP 地址。

我使用 Traefik 1.8 安装了标准的 k3s。如几个 github 问题所示,我已将所有服务设置为使用 Clusterip,并为我的 Traefik 和 apache 服务设置 externalTrafficPolicy: Local:https://github.com/k3s-io/k3s/issues/1652

奇怪的是,Traefik 似乎传递了任何像 x-forwarded-for 这样的标头,因为如果我手动将带有我的 IP 地址的 x-forwarded-for 添加到我的浏览器请求中,则 apache 日志中的结果有我的 ip 以及内部集群 ip 用逗号分隔。

当流量进入应该注入 IP 地址的集群时,是否有什么东西在 Traefik 实例之前被命中?

【问题讨论】:

【参考方案1】:

看来有很多事情会导致这个问题。就我而言,这是更常见的问题之一。我只需要修补 k3s traefik 清单即可拥有 hostNetwork: true。

kubectl patch deployment traefik --patch '"spec":"template":"spec":"hostNetwork":true'

需要注意的是不建议手动修改这个manifest,因为它是由helm管理的。因此,如果 helm 进程再次运行或重新安装或更新 k3s,它将恢复,您将不得不再次运行此补丁。您必须为 traefik 修改 k3s helm 图表或实施您自己的图表来代替 k3s 以使此更改生效。

【讨论】:

以上是关于使用 istio 后如何获取客户端真实 IP的主要内容,如果未能解决你的问题,请参考以下文章

如何获取网站用户的真实IP

使用LVS或者阿里云的SLB后如何获取访客真实的IP地址

如何使用 IOCP 获取客户端真实 IP 地址和端口?

如何获取伪装ip下的真实ip地址

服务器架构前面加了防火墙,Nginx如何获取客户端真实ip???

java如何获取用户真实的ip