HAProxyCompat
Restores the real client IP on modded servers behind a reverse proxy (FRP, nginx, HAProxy, Traefik) by reading the PROXY protocol (v1/v2).
截图
介绍
HAProxyCompat
Stop seeing 127.0.0.1. See who’s actually connecting.
When your Minecraft server sits behind a reverse proxy like FRP, nginx, HAProxy, or Traefik, every
player looks like they’re connecting from the proxy. Bans, logs, and IP tools all see the proxy’s
address instead of the real one. HAProxyCompat fixes that. It reads the PROXY protocol header
(v1 and v2) that your proxy sends, pulls out the real client IP, and hands it to Minecraft as if the
player connected directly.
The result: real IPs in your logs, working IP bans, and accurate geolocation. No client mod, no
extra setup for players.
Heads up: this is often not optional. Once your proxy starts sending PROXY headers, a vanilla
server has no idea what those extra bytes are and chokes on them, so players can’t connect and the
server just looks offline in the client. Installing HAProxyCompat is what makes the connection work
at all. The real-IP part is the bonus.
- For: NeoForge and Fabric dedicated servers. One jar covers every supported loader and version.
- Needs: Nothing else. The one Netty piece Minecraft doesn’t ship is tucked inside the jar for you, so it stays a single drop-in file.
Supported versions
| Loader | MC versions |
|—|—|
| NeoForge | 1.21 to 1.21.11, 26.1.x, 26.2.x, 26.3.x |
| Fabric | 26.1.x, 26.2.x, 26.3.x |
Fabric on 1.21.x is covered by the older 1.0.1 release (haproxycompat-fabric-1.21-1.0.1.jar),
which still works but no longer gets updates.
Quick start
- Drop the jar into your server’s
mods/folder. - Tell your proxy to send the PROXY header (see Point your proxy at it).
- If your proxy runs on a different machine, add its IP to
trusted_proxies(see below). - Start the server. Done.
Out of the box it works for a proxy running on the same machine as the server. That’s the only case
that needs zero config.
Configure it
NeoForge: settings live in config/haproxycompat-common.toml. Edit them while the server is
running and they apply instantly, no restart needed.
Fabric: settings live in config/haproxycompat.json. Restart required for changes to take effect.
# 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."
}
Settings
- enabled: master on/off switch.
- require\_proxy\_protocol: when
true, only allow connections with a valid PROXY header from a trusted proxy. Use when the Minecraft port is reachable only through your proxy. Whenfalse, also allow plain direct connections through untouched. - trusted\_proxies: IP addresses / CIDR ranges that may send PROXY headers. Only these are believed; anyone else sending a PROXY header is dropped. Add your proxy’s address here.
- log\_connections: print one line per connection decision. Great for debugging, noisy once working.
- kick\_message: message shown in the disconnect screen when a client connects directly and
require_proxy_protocolis true. Without this, clients would hang until a read timeout fires.
Why trusted_proxies matters
The PROXY header is just text the connecting side sends. Anyone who can reach your server port
directly could send a fake one and claim to be any IP they like, which would let them dodge bans or
frame someone else. To stop that, HAProxyCompat only believes the header when it comes from an
address you’ve listed in trusted_proxies. Everyone else is ignored or dropped.
Two simple rules:
- Add your proxy’s real address. The default list only trusts the local machine. If your proxy lives on another host or subnet, its headers get rejected until you add its IP or CIDR here.
- Lock the door behind the proxy. Firewall the Minecraft port so only your proxy can reach it. That way a forged header can never arrive in the first place.
If the list is empty, nobody is trusted and no real IPs get applied. The server logs a warning at
startup so you’re not left guessing.
Point your proxy at it
HAProxyCompat only listens. Your proxy still has to be told to send the header:
- HAProxy: add
send-proxy(v1) orsend-proxy-v2to theserverline. - nginx (stream): set
proxy_protocol on;in theserverblock. - FRP: set
transport.proxyProtocolVersion = "v2"on the proxied service. - Traefik: enable
proxyProtocolon the TCP service’s server.
Build from source
You need a JDK 21 or newer to run Gradle; it downloads the exact toolchain it needs.
gradlew.bat build
The jar lands in build/libs/haproxycompat-<version>.jar (ignore the -slim one, it lacks the
bundled Netty codec).
Testing
serverTest starts real dedicated servers with the built jar and talks to them over the Minecraft
protocol: status pings and logins with PROXY v1/v2 headers, a PROXY LOCAL health check, direct
connections (kicked, red X in the server list) and a PROXY header from an untrusted address.
:: Default set: the range endpoints of each version line
gradlew.bat serverTest
:: Every supported loader and version
gradlew.bat serverTest -Ptargets=all
:: Pick targets (a bare loader means all of its versions)
gradlew.bat serverTest -Ptargets=neoforge:26.3,fabric
Servers are installed once into .servertest/ (the newest NeoForge build / Fabric Loader for each
version) and reused on later runs. Running it accepts the Minecraft EULA for those test servers.
Each run leaves its console output in .servertest/<target>/servertest-latest.log.
Under the hood
Every new connection first meets a small gatekeeper (ProxyProtocolDetector) that sits at the very
front of the network pipeline. It peeks at the opening bytes to see if a PROXY header is there, and
checks whether the connection came from a trusted proxy. Then it decides what to do:
| From a trusted proxy? | Has a PROXY header? | What happens |
|—|—|—|
| Yes | Yes | Decode the header and apply the real client IP |
| No | Yes | Close the connection. Someone’s trying to spoof an IP |
| Any | No | Kick with kick_message and show a red X in the server list (or let it through, if require_proxy_protocol is off) |
When a header should be read, the gatekeeper hands the bytes to Netty’s own PROXY parser, grabs the
real address, and writes it straight onto Minecraft’s connection object. That last step happens the
moment the header arrives, which is the trick that makes the IP show up everywhere: in the join log,
in ban checks, and anywhere else the server asks “who is this?”. Health-check pings that carry no
real client (the PROXY LOCAL command) are recognized and left alone.
It’s a dedicated-server-only mod, so it never touches singleplayer or LAN worlds.
One jar serves both loaders: it carries both neoforge.mods.toml and fabric.mod.json, and each
loader only reads its own. All supported versions run on Mojang’s own class names, so the same
compiled mixins work everywhere. NeoForge uses ModConfigSpec for live-reloading config; Fabric
reads haproxycompat.json at startup.
License
GPL-3.0-or-later. See LICENSE. The bundled netty-codec-haproxy (relocated to
xyz.atmerek.haproxycompat.shadow.haproxy inside the jar) keeps its own Apache-2.0 license.
常见问题
HAProxyCompat 支持哪些 Minecraft 版本?
HAProxyCompat 支持 Minecraft Java 版 1.21–26.3,共 17 个版本,可用的加载器:Fabric / NeoForge。下载时注意选择和你游戏版本一致的文件。
HAProxyCompat 怎么安装?
先用 PCL2 或 HMCL 启动器安装对应版本的 Fabric / NeoForge,再把下载的 .jar 文件放进游戏目录的 mods 文件夹,重新启动游戏即可。开启了版本隔离的,mods 文件夹在 versions/版本名 下面。运行环境:仅服务端。
the_atmerek 的其他作品
查看全部 →
Contraption Lights (Bi-directional Coloured Dynamic Lights)
Adds coloured dynamic lights that move with your Create contraptions and Sable sub-levels, flowing both ways between your builds and the world.
Contraption Lights (Bi-directional Coloured Dynamic Lights)
Adds coloured dynamic lights that move with your Create contraptions and Sable sub-levels, flowing both ways between your builds and the world.
Create: Bits ‘n’ Tracks Community Edition
Create addon adding flanged cogwheels driven by Sable physics, for building working tank tracks. Community continuation of Bits 'n' Tracks by qwxon.
评论
登录后评论和评分