Links
Tags
Creators
Details
1.2.0
Compatibility
Changes
MikuHAProxy 1.2.0 —— 修掉「客户端连接被中断」被误报成判定异常的假警报。
这一版的核心是一个误报问题:网络层的正常中断(最常见的是端口扫描、探活、玩家在加载中途退出)会被当成「PROXY 判定阶段发生异常」刷进 ERROR 日志,并计入 status 的「异常」计数,让服主以为插件出了故障。此外还修掉了插件数据目录每次启动都重复改名,以及文档里把 Velocity 的配置项名写错的地方。
修复
-
连接被对端中断不再被误报为判定失败。判定逻辑改为按异常类型分类(不匹配日志文本,因为同一语义在不同平台措辞不同):
IOException族(Connection reset、Broken pipe、ClosedChannel、读取超时、SSLException、EOFException)⇒ 归为「连接中断」,不再计入失败计数、不再写 ERROR,仅在DEBUG级别留一行;HAProxyProtocolException⇒ 才是真正的「判定失败」(多半是有人在伪造 PROXY 头),照旧计入失败并写 ERROR;- 其余无法归类的异常 ⇒ 保守按判定失败处理。 异常原因链的遍历带深度上限(16 层)。深度截断时一律保守判为「判定失败」,确保藏在深层的伪造头信号不会被降级成噪音。
-
限流槽按键分类分开。此前限流器只按来源地址分槽,攻击者可以先用一次中断占住槽位,把随后「伪造 PROXY 头」的 ERROR 在限流窗口内挤掉。现在按「日志分类 + 来源地址」分槽,中断日志与真实信号互不影响,跟踪内存上界不变。
-
插件数据目录不再每次启动重复改名。此前比较的是 Velocity 用插件 id 拼出的路径字符串(恒为小写),而目标名含大写,于是每次启动都判定「需要改名」并重做一次;第二步失败时还可能把目录留在
*_renaming状态。现在改为查询磁盘上的真实名称,名字已正确就直接跳过,不再做无谓的移动。 -
修正
velocity.toml配置项文案。文档与日志此前把它写成proxy-protocol,真实键名是haproxy-protocol。功能一直未受影响(插件是通过 Velocity 的isProxyProtocol()方法读取该开关的,键名到字段的映射由 Velocity 负责),但照文档配置会找不到对应项。README 与启动日志共 30 处已全部改正。
兼容性
- 需要 Velocity 4.x(Java 25)。
- 配置项与白名单格式与 1.1.0 完全一致,可直接替换 jar。
config.toml的键名与默认值都没有变动,只是注释里补充了第三类日志(连接中断,仅 DEBUG)与「限流槽」的说明。 - 升级后
/mikuproxy status的「异常」计数会只统计真正的判定失败,数值比之前低是正常的。
需要注意
- 若你之前被
连接初始化(PROXY 判定)阶段发生异常 ... Connection reset这类日志困扰过,升级后它们不会再出现在 ERROR 级别。想看它们(排查网络问题时)请把日志级别开到DEBUG。
MikuHAProxy 1.2.0 — fixes a false alarm that reported dropped client connections as decision failures.
The core of this release is a false positive: ordinary network interruptions (port scans, health probes, players quitting mid-load — most commonly a Connection reset) were logged at ERROR as "exception during the PROXY decision phase" and counted under "Errors" in status, making server owners think the plugin had broken. Also fixed: the plugin's data directory was renamed on every startup, and the documentation used the wrong name for Velocity's config option.
Fixed
-
A connection reset by the peer is no longer reported as a decision failure. Classification is now done by exception type (never by matching log text, since the same condition is worded differently across platforms):
- The
IOExceptionfamily (Connection reset,Broken pipe,ClosedChannel, read timeouts,SSLException,EOFException) is treated as a connection interruption: it is no longer counted as a failure and no longer logged at ERROR — just one line atDEBUG. HAProxyProtocolExceptionis a genuine decision failure (usually someone forging PROXY headers): still counted and still logged at ERROR.- Anything unclassifiable is conservatively treated as a decision failure. The cause chain is walked with a depth limit (16 levels). When the walk is cut short by that limit, the result is conservatively treated as a decision failure, so a forging signal buried deeper can never be downgraded to noise.
- The
-
Log-throttle slots are now separated by category. Previously the throttle keyed only on the source address, so an attacker could spend the slot with one interruption and push the following forged-PROXY-header ERROR out of the throttle window. Slots are now keyed on log category + source address, so interruption logs and real signals no longer interfere — with the same memory bound as before.
-
The plugin data directory is no longer renamed on every startup. The check compared a path string built by Velocity from the plugin id (always lowercase) against the target name containing uppercase, so it decided a rename was needed on every start and redid it; a failure on the second step could also leave the directory stuck as
*_renaming. It now asks the filesystem for the real name and skips the work when the name is already correct. -
Corrected the
velocity.tomloption name in the docs and logs. It was documented asproxy-protocol, but the real key ishaproxy-protocol. Nothing was ever functionally affected — the plugin reads the switch through Velocity'sisProxyProtocol()method, and Velocity maps the key to the field — but following the docs would leave you unable to find the option. All 30 occurrences across the README and startup logs are fixed.
Compatibility
- Requires Velocity 4.x (Java 25).
- Configuration and whitelist format are unchanged from 1.1.0 — drop-in replacement. No
config.tomlkeys or defaults were changed; only comments were extended to describe the third log category (connection interruption, DEBUG only) and the "throttle slot" wording. - After upgrading, the "Errors" counter in
/mikuproxy statuscounts only genuine decision failures, so a lower number than before is expected.
Please note
- If you were bothered by lines like
连接初始化(PROXY 判定)阶段发生异常 ... Connection reset, they will no longer appear at ERROR after upgrading. To see them (useful when debugging network issues), enableDEBUGlogging.
作者:JunXieX | 所属:MikuMC 服务器
MikuMC 系列插件交流群:1105054380
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:SPh6m4k5:j0USYW9a"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:SPh6m4k5:j0USYW9a"
}

