andylizi
本帖最后由 andylizi 于 2023-1-25 08:29 编辑

背景
HAProxy 是一个高性能的TCP反向代理/负载均衡器,其功能类似于 Nginx。新版本的 BungeeCord 内置了对 HAProxy 的支持,使其能获取到客户端的真实IP。这一点跟 Spigot 的 BungeeCord 支持十分相似。但同样与 Spigot 相似的是,当开启了代理支持后,不用代理就无法进入服务器了。这给一些网络架构的部署带来了不便。


简介
HAProxyDetector 可以让 BC、Velocity 或 Spigot 同时接受 HAProxy 的代理连接与直连连接,使得下图的架构成为可能:

插件自身十分轻量级,开启后不会带来任何性能损失,资源占用可以忽视。

v2.0 更新:现已支持 Spigot 独立服务器,不再需要 BC 套壳。

v3.0 更新:现已支持 Velocity


效果图



使用方法(必读!!)

Spigot 注意事项:需要 ProtocolLib 插件作为前置才能运行。BC 上安装本插件后,Spigot 子服不再需要安装,只需要把其自带的IP转发功能打开即可(spigot.ymlbungeecord 选项与 ip_forward 选项)。
  • 如果遇到了 If you wish to use IP forwarding, please enable it in your BungeeCord config as well 错误,那就是 ip_forward 没开)
  • 目前插件的正式版 v3.0.1 暂时不支持 ProtocolLib v5.0.0,但是快照版本支持,详情请见这里

Paper 注意事项:新版 Paper 中自带了 HAProxy 支持(但不能直连),不能与本插件一起使用,请在 paper.yml 中关闭 proxy-protocol 选项。

BungeeCord 注意事项:需要在 BC 配置文件 config.yml 中打开所有 listenerproxy_protocol 选项才可正常使用。注意它跟 paper.yml 里的同名选项没有联系,不要开错了!

Velocity 注意事项:需要在 Velocity 配置文件中打开 haproxy-protocol 选项才可正常使用。

HAProxy 注意事项:只有在开启了 HAProxy 的 send-proxy-v2 选项后,插件才能获取到真实IP。如果不开的话显示的 IP 全都是 HAProxy 自身的。

Java 9+ 注意事项:如果遇到 NoClassDefFoundError: sun.misc.UnsafeInaccessibleObjectException 之类的错误,请添加 JVM 参数 --add-opens java.base/java.lang.invoke=ALL-UNNAMED

Java 18+ 注意事项:如果遇到 IllegalAccessException: static final field has no write access 错误,请更新插件到最新版本。

CatServer 注意事项:黑魔法太多太诡异,因此不支持。可以外面套一层 Waterfall。

安全警告:同时允许直连代理和连接会带来严重的安全问题:玩家可以自己架设一个 HAProxy,通过它来连接服务器“源站”,这样可以欺骗服务器的真实 IP 获取功能,将自己的来源 IP 修改为任意地址。

为了解决这个问题,本插件采用了 IP 白名单机制。只有白名单内的 IP 才允许通过 HAProxy 代理协议来连接服务器;直接连接不受影响。默认的白名单只包括 localhost,请在安装后编辑配置文件 whitelist.conf,添加自己的 HAProxy 实例的地址。
  1. # 允许的代理 IP 列表 whitelist.conf
  2. #
  3. # 留空则为禁止所有代理 IP
  4. # 每一行的内容为 IP,域名或 CIDR
  5. # 填写的域名只有在启动时会被解析一次
  6. # 每个域名可以包含多个 A/AAAA 记录,所有记录的 IP 都会被允许
  7. # 域名不能使用 CIDR 前缀

  8. 127.0.0.0/8
  9. ::1/128
复制代码
出于安全考虑,插件通常不允许关闭白名单。如果你出于测试之类的目的必须要关闭的话,请在文件最开头加入以下内容:
  1. YesIReallyWantToDisableWhitelistItsExtremelyDangerousButIKnowWhatIAmDoing!!!
复制代码
必须一字不差,并且在它之前除了注释外不能出现别的条目。


命令&权限
没有


下载
haproxy-detector-3.0.2.jar (102.93 KB, 下载次数: 342)
或 Github Releases:https://github.com/andylizi/haproxy-detector/releases
使用前请务必完整阅读注意事项!


开源

https://github.com/andylizi/haproxy-detector


隐私政策
此插件使用 bStats 进行匿名使用数据统计,详见 bStats 隐私政策。众多知名插件如 EssentialX、WorldEdit、Vault 等均使用了 bStats 服务。
你可以在这里浏览此插件的报告:Bukkit | BungeeCord | Velocity
可在 plugins/bStats/config.yml 文件中将 enable 设为 false 为你的服务器全局关闭此功能。


其他
此插件最初由 @梦 定制,经许可后开源&发布。
本贴不涉及 HAProxy 本体的安装与配置,请不要询问 HAProxy 自身的问题(因为我自己也不会




本插件所用所有代码均为原创,不存在借用/抄袭等行为

阿哲。
emm现在最求的就是一份教程了 插件感觉好 就是不会用

Fraely
请这位艺术家排版认真一点(狗头

SkyCatcher
这个还是很实用的,后面考虑出单服架构的spigot插件么

andylizi
本帖最后由 andylizi 于 2020-8-27 22:40 编辑
SkyCatcher 发表于 2020-8-27 17:53
这个还是很实用的,后面考虑出单服架构的spigot插件么

理论上倒是很简单(跟BC一模一样),但因为 spigot 的 netty 配置是写死在 nms 里的,想用反射修改的话非常麻烦,而且可能会影响与 ProtocolLib 的兼容性。

虽然 ProtocolLib 为了实现它自己的功能有一套修改 netty 管线的代码,但它的代码也是写死的,也不好用反射修改利用。可能到头来最方便的方式只能是用 javaagent+asm 改字节码才行…总之十分麻烦。

SkyCatcher
andylizi 发表于 2020-8-27 18:05
理论上倒是很简单(跟BC一模一样),但因为 spigot 的 netty 配置是写死在 nms 里的,想用反射修改的话非 ...

spigot下已经有人写了识别proxy protocol的插件了,所以只需要兼容下应该就可以了,你可以参考下
https://github.com/thijsa/SpigotProxy

bird。
哇~ 终于有人整这种插件了也!

andylizi
SkyCatcher 发表于 2020-8-27 18:27
spigot下已经有人写了识别proxy protocol的插件了,所以只需要兼容下应该就可以了,你可以参考下
https:/ ...

它这个的问题跟 ProtocolLib 类似,很难直接用反射处理。

但我再次看 ProtocolLib 的代码时突然想到了新思路。现在 v2.0 版已经支持 Spigot 了。

SkyCatcher
andylizi 发表于 2020-8-27 22:25
它这个的问题跟 ProtocolLib 类似,很难直接用反射处理。

但我再次看 ProtocolLib 的代码时突然想到了新 ...

你这个更新速度快的有点离谱……  所以如果用在spigot上时,还需要单独找个让spigot兼容proxy protocol的插件吗,还是说你已经把这功能包含进去了

andylizi
SkyCatcher 发表于 2020-8-27 22:31
你这个更新速度快的有点离谱……  所以如果用在spigot上时,还需要单独找个让spigot兼容proxy protocol的 ...
你这个更新速度快的有点离谱





嗯包含进去了。他这个 SpigotProxy 的代码写的……一言难尽。虽然用了一些反射但各种成员名称还是硬编码的,有些地方干脆反射都不用了,不知道能兼容到哪个版本…有些调试用的日志输出甚至都没删……

其实技术难点主要在新连接的 pipeline 初始化时能够截获并注入自己的 handler,只要这一点能实现剩下都好办,毕竟代理的协议支持是 netty 自带的。

我是未见
这插件一看就好强 但是暂时还看不懂到底起到了什么作用。。

Z_Dreams_
这……这算是诈尸吗
上次见你还是不知道几年前的ColorMotd、SuperBan那会儿

gundami
楼主nb,有了这个配合我的prism能在实现单端口多服分流的情况下还能获取原始用户ip
**兹磁!

迷离丶不羁
本帖最后由 迷离丶不羁 于 2020-11-23 13:46 编辑

您好,请问frp开启之后服务端报错是什么原因呢服务端为Mohist 1.12.2

报错如下:

[13:32:26 WARN]: [HAProxyDetector] Exception while detecting proxy
java.util.NoSuchElementException: haproxy-decoder
        at io.netty.channel.DefaultChannelPipeline.getContextOrDie(DefaultChannelPipeline.java:1080) ~[DefaultChannelPipeline.class:?]
        at io.netty.channel.DefaultChannelPipeline.addAfter(DefaultChannelPipeline.java:311) ~[DefaultChannelPipeline.class:?]
        at io.netty.channel.DefaultChannelPipeline.addAfter(DefaultChannelPipeline.java:299) ~[DefaultChannelPipeline.class:?]
        at net.andylizi.haproxydetector.HAProxyDetectorHandler.decode(HAProxyDetectorHandler.java:69) [haproxy-detector-2.0.jar:?]
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411) [ByteToMessageDecoder.class:?]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248) [ByteToMessageDecoder.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:?]
        at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287) [IdleStateHandler.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) [DefaultChannelPipeline$HeadContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [AbstractChannelHandlerContext.class:?]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) [DefaultChannelPipeline.class:?]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134) [AbstractNioByteChannel$NioByteUnsafe.class:?]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:624) [NioEventLoop.class:?]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:559) [NioEventLoop.class:?]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:476) [NioEventLoop.class:?]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438) [NioEventLoop.class:?]
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) [SingleThreadEventExecutor$5.class:?]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_201]

andylizi
迷离丶不羁 发表于 2020-11-23 13:43
您好,请问frp开启之后服务端报错是什么原因呢服务端为Mohist 1.12.2

报错如下:

mod 服应该是不支持的,对底层逻辑的修改太多了。这个没什么好办法能解决

逆天域
本帖最后由 逆天域 于 2021-1-12 18:44 编辑

所以还是找不到让基岩服务器接收真实IP的方法=-=

xx578975893
这个是用来干嘛的.看着有点懵逼

Mo_Cha_666
好人,正需要,是不是可以替代frp

FW-CornWorld
感谢dalao分享
已经在尝试了

金银白花
给份基础haproxy配置吧,求求了

J8964149
支持楼主!正好需要,良心

3585254862
子服要安装这插件吗

备胎橙子
感谢作者制作和分享这么好的插件

小阳儿_
其实出这类的东西我都觉得应该出个教程,毕竟我BC游戏内连接都还没搞明白,虽然说你们都说插件简单插件简单,但是一个教程都没说,就是好处是什么...

Hunter_Jun
牛逼!!!Mohist1.16.5+frp完美获取了真实IP!!!大梨子牛逼!!

我不是ZN
非常喜欢这个插件 解决了authme 穿透服无真实ip的登录问题
求更新支持1.18!

andylizi
我不是ZN 发表于 2021-12-6 19:29
非常喜欢这个插件 解决了authme 穿透服无真实ip的登录问题
求更新支持1.18! ...

唔,你试过它不支持 1.18 吗?有没有报错信息什么的

巧克力MOD
来波教程岂不美哉

yupaopao11
感谢分享.插件正好需要!

箱子菌
您好,用了https://github.com/games647/FastLogin之后会失效()可以的话能排查一下吗(虽然我知道大概率是那个插件的问题

春节里的走马灯
什么时候支持nps?

Ayamuta
本帖最后由 Ayamuta 于 2022-3-12 15:22 编辑

waterfall
客户端卡在 登陆中 界面
bc的信息
  1. [Netty Worker IO Thread #3/WARN] [io.netty.util.concurrent.AbstractEventExecutor]: A task raised an exception. Task: net.md_5.bungee.connection.InitialHandler$6$1@7d477f1d
  2. java.lang.Error: Method became inaccessible: PostLoginEvent(player=Ayamuta)
  3.         at net.md_5.bungee.event.EventBus.post(EventBus.java:53) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  4.         at net.md_5.bungee.api.plugin.PluginManager.callEvent(PluginManager.java:466) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  5.         at net.md_5.bungee.connection.InitialHandler$6$1.run(InitialHandler.java:550) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  6.         at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  7.         at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  8.         at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  9.         at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  10.         at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  11.         at java.lang.Thread.run(Unknown Source) [?:?]
  12. Caused by: java.lang.IllegalAccessException: class net.md_5.bungee.event.EventHandlerMethod cannot access a member of class net.andylizi.haproxydetector.bungee.BungeeMain$1TrackingStatsListener with modifiers "public"
  13.         at jdk.internal.reflect.Reflection.newIllegalAccessException(Unknown Source) ~[?:?]
  14.         at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source) ~[?:?]
  15.         at java.lang.reflect.Method.invoke(Unknown Source) ~[?:?]
  16.         at net.md_5.bungee.event.EventHandlerMethod.invoke(EventHandlerMethod.java:19) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  17.         at net.md_5.bungee.event.EventBus.post(EventBus.java:50) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  18.         ... 8 more
  19. [07:49:59] [Netty Worker IO Thread #7/INFO]: [/180.233.233.233:1603] <-> InitialHandler has connected
  20. [07:49:59] [Netty Worker IO Thread #8/INFO]: [/219.233.233.233:39803] <-> InitialHandler has connected
  21. [07:49:59] [Netty Worker IO Thread #8/WARN] [io.netty.util.concurrent.AbstractEventExecutor]: A task raised an exception. Task: net.md_5.bungee.connection.InitialHandler$6$1@4abdf866
  22. java.lang.Error: Method became inaccessible: PostLoginEvent(player=JK_CAT)
  23.         at net.md_5.bungee.event.EventBus.post(EventBus.java:53) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  24.         at net.md_5.bungee.api.plugin.PluginManager.callEvent(PluginManager.java:466) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  25.         at net.md_5.bungee.connection.InitialHandler$6$1.run(InitialHandler.java:550) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  26.         at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  27.         at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  28.         at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  29.         at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  30.         at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  31.         at java.lang.Thread.run(Unknown Source) [?:?]
  32. Caused by: java.lang.IllegalAccessException: class net.md_5.bungee.event.EventHandlerMethod cannot access a member of class net.andylizi.haproxydetector.bungee.BungeeMain$1TrackingStatsListener with modifiers "public"
  33.         at jdk.internal.reflect.Reflection.newIllegalAccessException(Unknown Source) ~[?:?]
  34.         at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source) ~[?:?]
  35.         at java.lang.reflect.Method.invoke(Unknown Source) ~[?:?]
  36.         at net.md_5.bungee.event.EventHandlerMethod.invoke(EventHandlerMethod.java:19) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  37.         at net.md_5.bungee.event.EventBus.post(EventBus.java:50) ~[waterfall-1.18-480.jar:git:Waterfall-Bootstrap:1.18-R0.1-SNAPSHOT:e767b40:480]
  38.         ... 8 more
复制代码

tuboaisi
        MCBBS有你更精彩~

andylizi
Ayamuta 发表于 2022-3-6 10:56
waterfall
客户端卡在 登陆中 界面
bc的信息

感谢反馈,新版本已修复(v3.0.1)

大米我这呢
很不错的插件支持作者加油!

魔月歌
感谢楼主分享

dsyq乌合之众
那么压测的话,还是压测的bc吗

梦彡星魂
本帖最后由 梦彡星魂 于 2022-8-9 16:58 编辑

开启代理,插件也装了,但是直连仍然无法连接是什么情况...版本1.18.2 无报错QAQ
追加编辑:用的Paper核心,才看到下面的回复,注意到最新版本支持Spigot且包含proxy protocol协议,但是我在paper.yml也打开了代理转发的功能,猜测与这一设置有冲突导致直连失败,准备测试

账号已弃用
是不是还没支持1.19

MinecraftHT
梦彡星魂 发表于 2022-8-9 16:13
开启代理,插件也装了,但是直连仍然无法连接是什么情况...版本1.18.2 无报错QAQ
追加编辑:用的Paper核心 ...

我也有同样的问题,不知道你测试的怎么样了,求结果

梦彡星魂
MinecraftHT 发表于 2022-8-15 22:38
我也有同样的问题,不知道你测试的怎么样了,求结果

1.检查Protocolib插件的版本,最新版似乎不兼容
2.paper配置文件关闭protocol协议

MinecraftHT
我是paper1.19 开启代理 安装插件后 请问如果需要允许的ip不在同一网段怎么办呢

andylizi
MinecraftHT 发表于 2022-8-16 19:09
我是paper1.19 开启代理 安装插件后 请问如果需要允许的ip不在同一网段怎么办呢 ...

可以添加多个不同的网段嘛?就像这样
  1. 103.21.244.0/22
  2. 103.22.200.0/22
  3. 103.31.4.0/22
  4. 104.16.0.0/13
  5. 104.24.0.0/14
  6. 108.162.192.0/18
  7. 131.0.72.0/22
复制代码

MinecraftHT
andylizi 发表于 2022-8-22 14:17
可以添加多个不同的网段嘛?就像这样

那没事了(可能是我配置出错了

魔法女猪壮壮
作者无敌牛,但是插件能支持1.7就好啦

ZzhangaAo1z_
为什么spigot.yml 的 bungeecord 选项改成true之后,连接服务器还是显示If you wish to use IP forwarding, please enable it in your BungeeCord config as well!

FreeNAP
真的是好插件,支持原创作者,MCBBS有你更精彩~

1282918234
请问能支持1.7.10嘛

cnjj
可以,很强大!

夜空星辰啊3
我不是ZN 发表于 2021-12-6 19:29
非常喜欢这个插件 解决了authme 穿透服无真实ip的登录问题
求更新支持1.18! ...

大佬可以分享一下吗,我也想用,能不能教一下

下一页 最后一页