HAProxyCompat

HAProxyCompat

通过读取 PROXY 协议(v1/v2),在位于反向代理(FRP、nginx、HAProxy、Traefik)后的模组服务器上恢复真实的客户端 IP。

工具

HAProxyCompat

不再看到127.0.0.1。看清楚到底是谁在连接。

当你的 Minecraft 服务器位于 FRP、nginx、HAProxy 或 Traefik 等反向代理后面时,每个玩家看起来都像是从代理服务器连接的。封禁、日志和 IP 工具看到的都是代理服务器的地址,而不是真实地址。HAProxyCompat 解决了这个问题。它能读取代理发送的 PROXY 协议头部(v1 和 v2),提取出真实的客户端 IP,并将其传递给 Minecraft,就像玩家直接连接一样。

结果就是:日志中显示真实 IP,IP 封禁功能正常工作,地理位置定位准确。无需客户端模组,也无需玩家进行额外设置。

注意: 这通常不是可选的。一旦你的代理开始发送 PROXY 头部,原版服务器无法识别这些额外的字节,会直接拒绝连接,因此玩家无法连接,客户端中服务器会显示为离线。安装 HAProxyCompat 是使连接正常工作的关键。而获取真实 IP 则是附带的福利。

  • 适用平台: NeoForge 和 Fabric 专用服务器。请选择与你的加载器和 MC 版本匹配的 JAR 文件。
  • 依赖: 无其他依赖。Minecraft 未自带的一个 Netty 组件已包含在 JAR 文件中,因此它仍然是一个即插即用的文件。

快速开始

  1. 将正确的 JAR 文件放入服务器目录的 mods/ 文件夹中。
  2. 配置你的代理以发送 PROXY 头部(请参阅将代理指向它)。
  3. 如果你的代理运行在不同的机器上,请将其 IP 添加到 trusted_proxies 列表中(见下文)。
  4. 启动服务器。完成。

默认情况下,它适用于与服务器在同一台机器上运行的代理。这是唯一一个无需任何配置即可工作的场景。

配置方法

NeoForge – 设置位于 config/haproxycompat-common.toml。在服务器运行时编辑这些设置会立即生效,无需重启。

Fabric – 设置位于 config/haproxycompat.json。更改需要重启服务器才能生效。

# NeoForge (haproxycompat-common.toml)
[general]
    enabled = true
    require_proxy_protocol = true
    trusted_proxies = ["127.0.0.1/32", "::1/128"]
    log_connections = false
    kick_message = "This server requires a proxy connection."
// Fabric (haproxycompat.json)
{
  "enabled": true,
  "requireProxyProtocol": true,
  "trustedProxies": ["127.0.0.1/32", "::1/128"],
  "logConnections": false,
  "kickMessage": "This server requires a proxy connection."
}

设置项

  • enabled — 主开关。
  • require_proxy_protocol — true:只允许来自受信任代理且带有有效 PROXY 头部的连接。当 Minecraft 端口仅能通过你的代理访问时使用。false:同时允许普通的直接连接通过。
  • trusted_proxies — 允许发送 PROXY 头部的 IP 地址 / CIDR 范围。仅信任来自这些地址的头部;其他任何来源发送的 PROXY 头部都会被丢弃。在此处添加你的代理的地址。
  • log_connections — 每次连接决策时打印一行日志。调试时很有用,正常工作后会显得嘈杂。
  • kick_message — 当客户端直接连接且 require_proxy_protocol 为 true 时,在断开连接界面显示的消息。没有这个设置,客户端会一直挂起直到读取超时。

为什么 trusted_proxies 很重要

PROXY 头部只是连接方发送的一段文本。任何能直接访问你服务器端口的人都可以发送伪造的 PROXY 头部,声称自己是任意 IP,从而躲避封禁或陷害他人。为了防止这种情况,HAProxyCompat 仅信任来自你已在 trusted_proxies 中列出的 IP 地址的头部。其他所有人的头部都会被忽略或丢弃。

两个简单的规则:

  1. 添加你代理的真实地址。 默认列表只信任本机。如果你的代理位于其他主机或子网上,它的头部会被拒绝,直到你在此处添加其 IP 或 CIDR 范围。
  2. 在代理后面锁好门。 设置防火墙,让只有你的代理能访问 Minecraft 端口。这样伪造的头部就根本无法到达服务器。

如果列表为空,则没有任何受信任的地址,真实 IP 不会生效。服务器在启动时会记录一条警告日志,这样你就不会感到困惑。

将代理指向它

HAProxyCompat 只负责监听。你的代理仍然需要配置为发送头部:

  • HAProxy: 在 server 行中添加 send-proxy(v1)或 send-proxy-v2(v2)。
  • nginx(stream): 在 server 块中设置 proxy_protocol on;。
  • FRP: 在被代理的服务上设置 transport.proxyProtocolVersion = "v2"。
  • Traefik: 在 TCP 服务的服务器上启用 proxyProtocol。

工作原理

每个新连接首先会遇到一个位于网络管道最前端的小型守门人(ProxyProtocolDetector)。它会检查连接的开头字节,判断是否包含 PROXY 头部,并检查该连接是否来自受信任的代理。然后它会决定做什么:

来自受信任的代理? 包含 PROXY 头部? 结果
是 是 解码头部并应用真实的客户端 IP
是 否 拒绝连接(如果 require_proxy_protocol 为关,则允许通过)
否 是 拒绝连接。有人试图伪造 IP
否 否 拒绝连接(如果 require_proxy_protocol 为关,则允许通过)

当需要读取头部时,守门人将字节传递给 Netty 自带的 PROXY 解析器,获取真实地址,并直接写入 Minecraft 的连接对象。最后一步发生在头部到达的那一刻,这也是使 IP 在各处都可见的诀窍:无论是在加入日志、封禁检查,还是在服务器询问“这是谁?”的任何其他地方。健康检查 ping(PROXY LOCAL 命令)不含真实客户端,会被识别并忽略。

这是一个仅适用于专用服务器的模组,因此永远不会触及单人游戏或局域网世界。

核心逻辑(ProxyProtocolDetector、ProxyProtocolHandler、混入代码)在两个加载器之间共享。NeoForge 使用 ModConfigSpec 实现即时重载配置;Fabric 在启动时读取 haproxycompat.json。