FRP + Nginx + Docker 真实客户端 IP 透传配置与抓包排查完整总结

VFX大学 Linux/macOS 与自动化运维 FRP + Nginx + Docker 真实客户端 IP 透传配置与抓包排查完整总结

正在查看 1 条回复
  • 作者
    帖子
    • #788

      追光
      管理员

      这里将部署 FRP + Nginx 获取真实 IP 配置,抓包排查流程,以及补充的 FRP HTTP/HTTPS 协议默认携带真实 IP 和抓包工具安装部分,整合成一个总结文档,方便续查阅和保存。

      一、背景

      • 你通过公网反向代理(FRP)访问本地 Docker 里的 Nginx 和 WordPress 服务

      • 需求:Nginx 能正确获取客户端真实 IP(而不是 127.0.0.1 或内网 IP)

      • 需要验证并调试过程中抓包确认数据包情况


      二、FRP 代理协议与客户端 IP 传递机制

      1. HTTP/HTTPS 代理类型(FRP

      type = http

      /

      https

      • FRP 默认自动为转发的 HTTP 请求添加真实客户端 IP 相关 HTTP 头:

        • X-Forwarded-For: 真实客户端 IP(多个代理时为链式列表)

        • X-Real-IP: 真实客户端 IP

        • 还有 X-Forwarded-Proto, X-Forwarded-Host 等头信息

      • 所以 HTTP/HTTPS 代理无需开启 proxy_protocol 选项,Nginx 只需正确配置读取上述头即可获得真实 IP


      2. TCP 代理类型(FRP

      type = tcp

      • 默认不带真实客户端 IP,因 TCP 层没有 HTTP 头

      • 需要开启并正确配置 proxy_protocol 传递 TCP 连接的原始 IP 信息

      • Nginx 也需要开启 proxy_protocol 支持并用 set_real_ip_fromreal_ip_header proxy_protocol 配合处理


      三、Nginx 配置示范

      server {
          listen 80;  # HTTP监听,若用 proxy_protocol 则需加 proxy_protocol 参数
      
          # 对于FRP HTTP代理,读取 X-Forwarded-For 头
          set_real_ip_from 0.0.0.0/0;          # 信任所有来源(可针对内网IP细化)
          real_ip_header X-Forwarded-For;
          real_ip_recursive on;                 # 递归查找真实IP(链式代理)
      
          # 其他正常配置
          server_name x.newvfx.com;
      
          # ...
      }

      注意:

      • 以上配置适合 FRP HTTP/HTTPS 代理

      • 如果你使用了 TCP 代理且开启 proxy_protocol v2,则监听写成:

        listen 80 proxy_protocol;

        并且改用:

      set_real_ip_from 127.0.0.1;
      real_ip_header proxy_protocol;
      • 但实际测试中,HTTP代理默认带 IP,TCP+proxy_protocol 反而复杂且容易出错


      四、FRP 配置示范

      HTTP 代理示例(推荐)

      [[proxies]]
      name = "Docker-Web-HTTP"
      type = "http"
      local_ip = "192.168.215.2"
      local_port = 80
      custom_domains = ["x.newvfx.com", "*.x.newvfx.com"]
      transport.use_encryption = true
      # 不要开启 proxy_protocol
      # transport.proxy_protocol_version = "v2"

      TCP 代理示例(仅当必要)

      [[proxies]]
      name = "Docker-TCP-Proxy"
      type = "tcp"
      local_ip = "192.168.215.2"
      local_port = 80
      remote_port = 8080
      transport.proxy_protocol_version = "v2"
      transport.use_encryption = true

      五、抓包工具安装与使用

      1. 安装抓包工具

      • Debian / Ubuntu

      sudo apt update
      sudo apt install tcpdump -y
      • CentOS / RHEL

      sudo yum install tcpdump -y
      • macOS

      系统默认带 tcpdump,无需安装

      • Windows

      使用 Wireshark(图形界面)或 WinDump(tcpdump Windows版)


      2. 抓包示例命令

      tcpdump -nnA -i eth0 port 80 | head -n 50
      • -nn :显示数字格式 IP 和端口,避免解析延迟

      • -A :显示 ASCII 格式,方便查看 HTTP 内容

      • -i eth0 :指定网卡接口,根据实际调整

      • | head -n 50 :限制显示 50 行,防止输出过多


      六、排查要点与总结

      阶段

      关键点

      说明

      公网 FRP 代理层

      HTTP 类型自动带 IP 头

      HTTP/HTTPS 代理自动添加真实客户端 IP 相关头部

      TCP 类型需开启 proxy_protocol

      TCP代理必须开启 proxy_protocol 才能传递原始 IP

      本地 Nginx 配置

      配合 FRP 协议选择合适配置

      HTTP代理读取 X-Forwarded-For,TCP代理用 proxy_protocol

      抓包确认数据包 IP

      通过 tcpdump 观察 IP 包

      可确认数据包发起 IP,辅助判断 IP 透传是否成功

      避免错误配置

      避免在 HTTP 代理开启 proxy_protocol

      HTTP 协议开启 proxy_protocol 会导致请求 400 Bad Request


      七、典型问题及解决

      • 开启 proxy_protocol v2 后,Nginx 只能看到 127.0.0.1 或本地 IP

        → 说明没正确匹配或使用了不兼容协议,通常 HTTP 代理不应开启 proxy_protocol

      • 不开启 proxy_protocol,Nginx 日志出现真实公网 IP

        → 正确,HTTP 代理已经自动带真实 IP

      • Nginx 配置 set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; real_ip_recursive on;

        → 简洁且通用,适用于信任所有上游代理的场景


      八、示例最终配置片段

      Nginx 监听配置

      server {
          listen 80;
      
          set_real_ip_from 0.0.0.0/0;
          real_ip_header X-Forwarded-For;
          real_ip_recursive on;
      
          server_name x.newvfx.com;
      
          # ... 其他配置
      }

      FRP 代理配置

      [[proxies]]
      name = "Docker-Web-HTTP"
      type = "http"
      local_ip = "192.168.215.2"
      local_port = 80
      custom_domains = ["x.newvfx.com", "*.x.newvfx.com"]
      transport.use_encryption = true

    • #792

      追光
      管理员

      1. transport.proxyProtocolVersion 的作用

      • 用于 TCP 代理场景,在连接头中加入 Proxy Protocol v1/v2,传递客户端 IP。

      • HTTP/HTTPS 代理不需要,因为已经有 X-Forwarded-ForX-Real-IP

      场景

      是否开启 v2

      IP 获取方式

      HTTP

      X-Forwarded-For

      HTTPS

      X-Forwarded-For

      TCP + Nginx

      Proxy Protocol

      TCP + SSH

      无需(直连)

      TCP + AI 模型

      无需(直连)


      2. 什么时候用 v2?

      • 仅在 TCP 穿透 → 后端有 Nginx 或其他支持 Proxy Protocol 的程序时使用。

      • 示例:

      listen 80 proxy_protocol;
      real_ip_header proxy_protocol;
      set_real_ip_from <FRP客户端IP>;
      • 如果后端没有 Nginx(如 SSH、大模型端口),不能开启 v2,否则连接报错(因为目标程序无法解析 Proxy Protocol 头)。


      3. HTTP 穿透(你的情况)

      • 默认 HTTP 类型的 FRP 已透传真实 IP。

      • 只需 Nginx 配置:

      set_real_ip_from 0.0.0.0/0;
      real_ip_header X-Forwarded-For;
      real_ip_recursive on;

      4. 为什么加 v2 出错?

      • 因为目标程序(SSH 或 AI 模型)期望 纯 TCP 流,收到 Proxy Protocol 头会解析失败,直接断开。


      一句话记忆

      • HTTP 场景:不用 v2,靠 X-Forwarded-For

      • TCP 场景:只有在后端支持 Proxy Protocol 时才加 v2,否则别加。

正在查看 1 条回复
  • 在下方一键注册,登录后就可以回复啦。