目前,frp 支持两种获取真实 IP 的方案:

  • XFF 请求头 (适用于 HTTP 隧道)
  • Proxy Protocol (适用于 TCP、UDP、HTTP、HTTPS 隧道)

请根据您穿透的本地服务选用合适的方案。

一、XFF 请求头

注意:该方案仅适用于 HTTP 隧道,不适用于 HTTPS、TCP、UDP 等隧道

使用 HTTP 隧道时,frpc 会自动将客户端的请求 IP 追加到 X-Forwarded-For 尾部,您的应用程序可以通过读取这两个请求头来获取客户端真实 IP。您可以参考 MDN 文档 获取更多信息。

请注意,XFF 头的前半部分是 用户完全可控 的,因此 前面的数据并不可靠。我们推荐您只读取最后一个 IP,并且总是做好数据过滤以防出现安全问题。

# 格式说明
X-Forwarded-For: <client>, <proxy1>, ..., <连接到 frps 的 IP>

# 假设连接到 frps 的 IP 为 114.51.4.191,下面是一些例子
X-Forwarded-For: 114.51.4.191
X-Forwarded-For: 127.0.0.1, 1.1.1.1, 6.6.6.6, 114.51.4.191
X-Forwarded-For: '; drop database natfrp --, 114.51.4.191

二、Proxy Protocol

注意:使用该方案时必须在本地服务也做相应的配置,只修改 frp 配置会造成 隧道完全不可用,UDP 隧道需更新到 0.42.0-sakura-4 以上才能使用此功能。

Proxy Protocol 是由 HAProxy 开发者 Willy 提出的一种反向代理协议,目前已被广泛支持。您可以参考 HAProxy 文档 获取更多信息。

启用 高级用户模式 并添加如下 隧道自定义设置 后,frpc 就会在请求本地服务时应用 Proxy Protocol 协议:

proxy_protocol_version = <v1|v2|simple>

目前 Proxy Protocol 有两个版本:v1 和 v2,请先调查您所使用的本地服务支持哪个版本再进行配置。如果两个版本都支持的,我们推荐您使用 v2 以提高传输效率。

Proxy Protocol v1 并未为 UDP 设计,在 UDP 隧道中您总是应该使用 v2。simple 对应由 Cloudflare 提出的 Simple Proxy Protocol,由于目前几乎没有应用支持,设置为该选项时务必谨慎操作。

大部分应用的 Proxy Protocol 支持开启后都将强制握手,即您无法在启用 Proxy Protocol 的同时允许不启用的客户端连接,
因此请确保您在隧道配置和应用配置中均启用 Proxy Protocol,并可能将无法通过本地/内网直连,只能通过隧道访问。

如希望本地和内网的直接连接不通过隧道,您可以使用 内网访问 功能来实现。

2.1、Web 服务器启用 Proxy Protocol 支持

提示:在某个 listen 端口启用 Proxy Protocol 后,该端口(包括其他配置文件中的相同端口)的所有连接都会按 Proxy Protocol 协议处理

因此,所有连接到该端口的客户端(frpc)都必须启用 Proxy Protocol 支持,否则会导致连接失败;使用浏览器也将无法直接访问该端口,可以使用内网访问功能在需要启用 Proxy Protocol 的 server 块找到 listen 字段,并在尾部(分号前面)添加用空格分开的 proxy_protocol 即可。举个例子:

修改前:

http {
    server {
        listen 80;
        listen 443 ssl;
        # ...
    }
}

修改后:

http {
    server {
        listen 80 proxy_protocol;
        listen 443 ssl proxy_protocol;
        # ...
    }
}

配置完成后,您可以通过 $proxy_protocol_addr 变量获取到真实 IP,可以将其设置为一个头部传递到后端应用等。

一个常见的做法是使用 realip 模块直接将结果覆盖到 $remote_addr

server {
    listen 80 proxy_protocol;
    listen 443 ssl proxy_protocol;

    # set_real_ip_from 需要设置为您运行 frpc 机器的内网 IP 或段,或设置为 127.0.0.0/8 表示来自本机
    set_real_ip_from 127.0.0.0/8;
    real_ip_header proxy_protocol;

    # 原有内容...
}

现在,您不需要任何其他操作,应用即可获取到真实 IP 了。

2.2、Minecraft 服务器启用 Proxy Protocol 支持

2.2.1、BungeeCord

请参考 BC 官方文档 进行配置,您可以搜索 proxy_protocol 找到对应内容(在页面底部)。

listeners:
- query_port: 25577
  motd: '&1Another Bungee server'

  # 新增此行
  proxy_protocol: true

2.2.2、Velocity

请参考 Velocity 官方文档 进行配置。示例修改如下:

prevent-client-proxy-connections = false

[advanced]
haproxy-protocol = true

如果您希望允许本地或内网直接连接,请使用 内网访问 功能来实现。
如果您希望通过游戏自身同时支持通过隧道和直连,请使用 HAProxyDetector 或选择一个积极维护的 Fork 分支 或精神续作,如:
Wuchang325/HAProxyReduce(仅支持 Velocity / Paper / Folia)
YBRC114514/haproxy-detector-BungeeCord(仅维护 BungeeCord)
并在安装前阅读项目 README 理解使用方法,注意审核和测试其中的 AI 成分代码。

声明:
本站所有文章,如无特殊说明或标注,均为本站原创发布。
任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。
如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。