找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888广告投放联系QQ68610888
glinet
查看: 670|回复: 0

Traefik 3 代理层层穿透,客户端真实 IP如何破局?

[复制链接]
发表于 2025-2-14 11:54 | 显示全部楼层 |阅读模式
我家里的网络均采用了 Traefik 3 作为 Web 入口网关,主要有三个,一个是 DMZ 区的网关,另两个为内部可信区域的网关。Web 代理层级难免会存在多级连的情形,取真实IP苦不堪言,本篇重点来讲讲 DMZ 的区网关配合内部应用获取客户端真实 IP 。这里顺便透漏个我选择 Traefik 作为网关一个原因是它内生支持 TCP 转发,暴露点 ssh 之类的协议嘎嘎香,比如 jumpserver 的 web 控制台和 ssh 入口统一由 Traefik 暴露,优雅而规范。
背景介绍
言归正传,DMZ 区的 Traefik 主要有四个暴露用户渠道。一是显示由 Cloudflare 反代访问形式,理论上同时支持 IPv4 和 IPv6 ,我其实关闭了 IPv6 的访问的,IPv6 的地理信息不健全,不便于管理。二是通过公网 IPv4 渠道,是通过打洞实现,现阶段暂未公开,但实际别人扫 IP 和端口是可以直达访问到的。三是公网 IPv6 渠道,这个 IPv6 地址也暂未对外公开解析,也就是没做 DDNS 解析,但实际也能被扫描端口直达访问的。四是通过内网 IP 访问,这个渠道是在接入家庭WIFI时的场景。大致四个访问渠道可简单归纳为如下示意图。




聊下痛点吧。看到这里其实我的访问需求是很明晰,网络架构也不是太复杂,但在实际网络管理过程中对客户端真实 IP 问题头疼至极,Traefik 的访问日志在这种网络架构下,如果 Traefik 不配置信任转发代理头,有些渠道的客户端 IP 是真实,有些又只能获取到前置代理 IP,这种不统一造成了阻碍排查、统计数据等诸多问题。那么在看下设置 X-Real-IP 头,在设置了信任转发头的可信网段后,如 CLOUDFLARE 的网段,直连渠道又无法设置 X-Real-IP ,步伐不统一,还是会扰乱网络管理。
前段时间我给家里布置了一套蜜罐系统,它取客户端的 IP 是从 XFF 头取的首个 IP ,如果恶意用户在 XFF 头伪造 IP ,会扰乱蜜罐系统的业务逻辑,给告警分析增加负担,还先去确认下 XFF 链,告警的这个远程IP是不是真实 IP ,如果外层网关做一定处理,清除掉伪造IP可以大大减轻这个负担。还有就是家里的 Web 应用防火墙 WAF 为了规范化管理,统一从 X-Real-IP头 取客户端真实IP,还有就是好些后端应用系统喜欢从 X-Real-IP 头提取真实 IP。这个网关比较特殊,既需要接收前置代理 Cloudflare 的代理流量,还需要接收外网直连流量,还需要接收内网客户端直连流量。该网关担负着获取真实IP的重担,它需要设置 X-Real-IP 和 X-Forwarded-For 这两个 HTTP 头,确保他们没有被恶意篡改,而官方的最佳实践配置是无法满足我这个场景需求的,终究还是从源码插件下手。评论区 1 楼即可免费获取。
找了网上有些插件,基本都是信任客户端传递来的特定 HTTP 头,没有核对前置端点是不是可信代理还是真实用户,本插件解决了如下问题:
  • 与内置信任转发头 forwardedHeaders.trustedIPs 轻松共用环境变量,降低维护代理 IP 成本
  • 重写 XFF 头,避免客户端伪造 IP,绕过 WAF 防护等
  • 重写 X-Real-IP 头,确保后端各类服务取到各个渠道访问的真实客户端 IP ,避免业务层来实现复杂判断逻辑

配置实践
这里以 Docker Compose 编排为例,在前期做的异地组网基础上改造。在 headscale 根目录下创建如下目录结构,并切换到新目录下
  1. mkdir -p traefik/plugins-local/src/github.com/evling2020/
  2. cd traefik/plugins-local/src/github.com/evling2020/
复制代码


然后克隆从我后台拿到的源码仓库地址,得到如下目录结构。




配置Cloudflare可信IP网段和本地可信代理IP地址,分别用两个环境变量表示,CLOUDFLARE_IPS 和 LOCAL_IPS




其中cloudflare我们可以用一个crontab计划任务执行脚本来动态更新.env中的环境变量,脚本内容如下:
  1. #!/bin/bash
  2. # 配置文件路径
  3. config_file="./.env"
  4. IPV4_LIST=$(curl -s https://www.cloudflare.com/ips-v4)
  5. # 如果 curl 失败,则退出并打印错误信息
  6. if [ $? -ne 0 ]; then
  7.     echo "Failed to fetch Cloudflare IPv4 addresses."
  8.     exit 1
  9. fi
  10. IPV6_LIST=$(curl -s https://www.cloudflare.com/ips-v6)
  11. # 如果 curl 失败,则退出并打印错误信息
  12. if [ $? -ne 0 ]; then
  13.     echo "Failed to fetch Cloudflare IPv6 addresses."
  14.     exit 1
  15. fi
  16. ALL_IPS=$(echo -e "$IPV4_LIST\n$IPV6_LIST" | tr '\n' ',')
  17. new_ips=""${ALL_IPS%,}""
  18. current_ips=$(grep "^CLOUDFLARE_IPS=" .env | cut -d'=' -f2-)
  19. echo new_ips: $new_ips
  20. echo current_ips: $current_ips
  21. # 如果当前值和新值不同,则更新配置文件
  22. if [[ "$current_ips" != "$new_ips" ]]; then
  23.     # 使用 sed 替换配置文件中的 CLOUDFLARE_IPS 环境变量值
  24.     sed -i "s#^CLOUDFLARE_IPS=.*#CLOUDFLARE_IPS=$new_ips#" "$config_file"
  25.    
  26.     # 输出新值确认替换是否成功
  27.     echo "CLOUDFLARE_IPS has been updated to:"
  28.     grep "CLOUDFLARE_IPS" "$config_file"
  29.     /usr/bin/docker compose up -d
  30. else
  31.     echo "CLOUDFLARE_IPS has not changed. No update needed."
  32. fi
复制代码


这个插件需要配合转发可信IP插件使用,在traefik的启动命令添加一行代码如下:
  1. - "--entrypoints.websecure.forwardedHeaders.trustedIPs=$CLOUDFLARE_IPS,$LOCAL_IPS"
复制代码


启动命令还需要加一行本文的主角插件
  1. - "--experimental.localPlugins.traefik-forwarded-real-ip.modulename=github.com/evling2020/traefik-forwarded-real-ip"
复制代码


随后引入环境变量到容器中,我这里对外的Traefik没有本地代理,就不引入了,仅引入Cloudflare的环境变量。




万事俱备,一键重建容器
  1. docker compose up -d
复制代码


有效性验证
伪造一个可信 Cloudflare 代理 IP 到 XFF 头,透过 CF 代理访问 wiki 蜜罐




查看蜜罐后台日志,发现伪造的 XFF 头已被正确清理掉,第二个 IPv6 为 Cloudflare 的反代 IP ,符合预期。




接着验证直连方式,通过强制指定 IP 形式访问我打洞出去的 Traefik 端口。




查看蜜罐后台,发现符合预期,伪造 XFF 正确被清理,蜜罐能正确呈现攻击源头,符合预期




最后再测试一个极端情况,倘若有人从可信代理 CF 来访问,比如 CF worker 代理方式会怎样。这里就不贴了,结果当然是符合预期的。
小结
其实到这,我再抛一个问题供思考,那么如何优雅地与内置白名单访问插件配合使用呢?那样岂不是更加完美哉!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
只谈技术、莫论政事!(点击见详情) | 互相尊重、友善交流、切勿过度反应、玻璃心。胡乱输入灌水等操作将会被封禁ID。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

欢迎大家光临恩山无线论坛上一条 /1 下一条

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2025-12-5 12:29

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com

快速回复 返回顶部 返回列表