一个基于Go语言的高性能多用户端口转发面板-隐藏你的BDS服务器IP

二次开发 软件资源 一个基于Go语言的高性能多用户端口转发面板-隐藏你的BDS服务器IP 1.0.0

完成注册/登录后下载
[MD] # v1.3.0 > ⚠️ **本版隧道协议硬切换 v4 → v5,旧客户端一律不被接受,两端必须成对升级。** > 升级顺序:**先服务端,再客户端**。客户端未升级期间只会握手失败并每 3 秒自动重试, > 服务端升级完成后把客户端升到本版即自动恢复,无需人工干预。 > > 本版同时包含 CHANGELOG 中 `v1.2.0` 条目的全部内容(NetherNet 透明代理,此前未单独发版)。 ## 亮点 - **Minecraft 基岩版 NetherNet(WebRTC)透明代理**:透明模式下新增开关,由信令网关 (重写 SDP candidate 为中转机公网地址)+ 数据多路复用器(按 `ice-ufrag` 用一个 UDP 端口承载全部玩家、以**透明源**转发)组成——后端 BDS 零改动、零插件,且**仍然看到 玩家真实 IP**。HTTP/HTTPS 双模式同端口嗅探;证书由用户粘贴 PEM 内容并在保存时用 `tls.X509KeyPair` 实配校验。新增配置项 `forward.public_ip`(NAT/容器下需手动指定)。 - **真机验证通过**:玩家可正常进服,`tcpdump` 可见完整双向流(玩家 → BDS、 BDS → 玩家经隧道回中转机)。 - ⚠️ **隧道协议硬切换 v4 → v5**:Hello 升为 v6 形态(154B,域标签 `pfapp-hello-v6`), Accept/Reject 标签同步升级;对 MAC 验证通过的旧客户端回跨版本拒绝,旧客户端显示 「被拒绝」而不是无应答。 ## 修复明细(NetherNet 全链路,均真机定位) | 问题 | 症状 | | --- | --- | | 信令请求经隧道被出/入向隔离丢弃 | 玩家拿 `Service unavailable`,直连 BDS 正常 | | 公网 IP 探测静默拿到 Docker 网桥地址 | candidate 写错、玩家连不上,且日志无痕迹 | | `SplitHostPort` 解析不带端口的 TargetAddr | 规则一律进错误态(面板红色徽标) | | 零指纹机器 Hello 退化 122B | 这台机器就是连不上,真实原因只是没指纹 | | STUN ufrag 取错段(`username[:len/2]`) | `InitialConnection-115` | | 注册会话用了信令端口而非数据端口 | 玩家进不来 | | SDP 重写把 CRLF 改成 LF | 客户端静默不进 ICE、零 STUN | | 多条 candidate 全重写成同一公网地址 | ICE 候选重复/畸形,静默不发 STUN | | answer 透传 BDS 的 `Content-Length` | `setRemoteDescription` 失败、`-115` | | 会话不回写注册表 → 回程路由推送 `count:0` | BDS 回包从后端机物理网卡漏出,`-83` | | 同一 ufrag 重复登记旧会话不 Close | 透明 socket 泄漏 + 玩家元组重连 `EADDRINUSE` | | `mergeStats` 漏接数据多路复用器 | 面板规则行/仪表盘恒 0 B,会话明细却有流量 | | 会话空闲回收 5 分钟 | 离线玩家 IP 久不释放,残留 /32 回程路由 | ## 升级注意 1. **先升服务端,再升客户端**(v1.1.x 客户端连不上新服务端;客户端后升期间自动重试)。 2. NAT/容器部署时 `forward.public_ip` 需手动指定(自动探测可能拿到内网地址, 探测结果落在私网/回环/链路本地时会显式告警)。 3. NetherNet 证书是用户粘贴的 PEM 内容(每用户自有域名/证书),保存时即校验配对, 上限 128KB。 4. NetherNet 会话空闲回收为 60 秒:离线玩家 IP 的回程路由约 1 分钟内自动回收。 ## 下载 | 附件 | 用途 | SHA256 | |---|---|---| | `go-port-forward-v1.3.0-linux-amd64.tar.gz` | 服务端(x86_64) | `a1044083b18b6f7cf89adf3602844651c2e642f5d6fa7214eb94e5131bef46b8` | | `go-port-forward-v1.3.0-linux-arm64.tar.gz` | 服务端(ARM64) | `cae5e178675409912d4dec7047351594b36057114b450b7675e50e45ff9dc268` | | `go-port-forward-v1.3.0-linux-arm.tar.gz` | 服务端(ARM32) | `f7724dc7c890423ac416ffe2ada900751cf79a973512d877683ea2647ba3f974` | | `pf-client-v1.3.0-windows-amd64.zip` | Windows 隧道客户端(exe 与 wintun.dll 必须同目录) | `9a29e0cd53a631ca96789940de5d225a13d24b71c934f288cd4e4eceabfea4cb` | | `checksums-sha256.txt` | 服务端产物校验和 | — | **升级指引**:服务端解压替换重启即生效;客户端 zip 解压替换 exe 与 wintun.dll。 **两端都必须升级**(协议硬切换),顺序为先服务端后客户端。 完整变更见 [CHANGELOG.md](https://github.com/272416939/go-port-forward/blob/main/CHANGELOG.md)。 [/MD]
本版本服务端与客户端可各自独立升级、任意混用(隧道协议兼容:v5 服务端接受 v4 客户端;
推荐先升级服务端再升级客户端)。同网多台克隆虚拟机部署是本版重点处理的场景。

克隆虚拟机指纹去重:设备指纹 v2 + 握手 Hello v5​

同一镜像克隆的虚拟机共享 Windows MachineGuid,设备指纹(派生自它)完全相同——
「一码绑一设备」的防线对克隆机失效:码可复制到任何克隆机上使用,服务端无法区分、无法
按机器吊销。

  • 客户端:设备指纹 v2 = MachineGuid 掺入 SMBIOS 系统UUID 再派生。UUID 由宿主机
    注入,Hyper-V/VMware 克隆虚拟机时主动更换(Proxmox/KVM 默认带 vmgenid),两台克隆机
    的指纹 v2 天然不同;SMBIOS UUID 不可用时自动经 CIM(Win32_ComputerSystemProduct)
    兜底读取,再不行回落主指纹(行为与旧版一致)。来源与失败诊断写入客户端运行日志。
  • 协议:Hello v5(在 v4 布局上追加 32 字节指纹 v2,进 MAC)。只动 Hello——
    Accept/Reject/会话/数据面零变化;v5 服务端接受 v4 客户端。
  • 服务端:绑定自动迁移。存量用户升级客户端后首次重连即完成迁移,零手动操作;
    迁移后旧指纹立即失效——把码拷到另一台克隆机会被拒绝。
  • 面板:同一指纹绑定在多个访问码上时显示「疑似克隆机」黄色警告。
升级须知:① 先升级服务端(对存量客户端无感),再升级客户端;② 每个访问码的
「绑定设备」码会在客户端升级后变更一次(面板与客户端 UI 同步显示新码),这是预期
行为不是异常;③ 同指纹的第二台克隆机在第一台迁移后会收到「设备不匹配」→ 面板解绑
一次即绑定自己的新指纹。

同网络多台客户端:握手串线自愈,不再误报「接入码可能已失效」​

NAT(EIM)端口复用/重映射会把一台机器的握手应答串到另一台机器的握手窗口。客户端现在:

  • 验签失败/结构非法的 Accept 一律排空、继续等本次自己的应答(串线提示进运行日志);
  • 握手整轮失败后自动更换本地端口重建 NAT 映射——「重启路由器/客户端」变成每轮
    自动动作;
  • 服务端对「同一来源地址已被另一访问码的会话占用」打限频 warn(排障锚点)。

服务端面板「往返延迟」恒为空(修复)​

TypePong 分支从未调用 RTT 观测(心跳注释写了「被动测量 RTT」但实现遗漏)。现在
Ping 发出记基线、Pong 验证后观测(EWMA)——对旧客户端即时生效。

其他改进​

  • 接入码弹窗显示隧道密钥独立字段(带复制;密钥本就内含于接入码,便于核对与手动配置)
  • 隧道子网广播(客户端固有噪音)的隔离丢弃从 warn 降为 debug,单播越界尝试保留 warn
  • 面板「连接数」列标注「活跃/累计」语义并加悬停说明
本版本服务端与客户端可各自独立升级、任意混用(隧道协议无变化,无需成对升级)。

服务端:透明模式跨规则共享绑定​

修复透明模式最疼的一个问题:同一条隧道下的多条透明规则现在可以同时服务同一批玩家。

透明转发为每个玩家会话以「玩家 IP:端口」为源绑定 IP_TRANSPARENT socket(源地址保真,后端零插件看到玩家真实 IP),该绑定在内核层面全机独占。旧实现每条规则各自 bind、没有跨规则协调——两条透明规则服务同一批玩家时(EIM NAT 端口复用 + 基岩版加服器 ping 全列表会把同一玩家的探测包打到多个透明端口),后到者 bind: address already in use 被丢弃,且绑定被赢家的会话持续刷新,输家在玩家持续探测期间永久断流(2026-09-02/09-03 两次现形,表现为某条规则的玩家全部进不去、客户端「上行恒 0、下行有动」)。

  • 新增全机唯一的「玩家元组 → 透明 socket」注册表:每个玩家元组全机只绑一个 socket,所有规则的会话共享(引用计数,最后一个释放才关);回程按「包源地址(=后端)」分发,各自从自己的监听端口发回玩家。内核回程链路零改动。
  • 玩家频繁在多条规则间切服不受影响:切新服即时共享既有绑定,旧会话按原空闲超时自然回收。
  • ⚠️ 行为变化:同一条隧道下透明规则的转发目标端口现在不可重复——两条规则指向同一后端 IP:端口会在保存时被拒绝(后端无法区分流量来自哪个入口,属无意义配置)。存量重复规则照常运行(运行时广播兜底),编辑任一条时会被提示改端口。

客户端:不再误报「接入码可能已失效」​

断开重连后客户端报「接入码过期或无效」、重启才恢复的问题。根因:断开后服务端旧会话在回收前仍向本地址发心跳与路由推送,快速重连时 NAT/OS 可能复用刚释放的源端口,残留包落进握手 socket,被误判为接入码失效。现在握手只认 Accept/Reject,其余残留包排空继续等(pf-client v1.1.0-1 起,本次首次进入发行版)。

v1.1.0​

⚠️ 两端必须成对升级:本版本包含隧道协议 v4(安全修复)。旧客户端连新服务端、新客户端连旧服务端都会被明确拒绝并提示升级(不再误报「服务端无应答」),但混用版本无法建立隧道。

升级方式

  • 服务端:下载对应架构 tar.gz,解压替换二进制后重启(配置文件 config.yaml 首次启动会自动补全新增配置项并备份原文件为 config.yaml.v<N>.bak)
  • 客户端:下载 pf-client zip,解压后整体替换(pf-client.exe 与 wintun.dll 必须同目录);直接覆盖安装即可,接入码与配置自动沿用

安全​

  • 隧道协议升级到 v4:修复 v3 两个方向共用一把密钥导致的每包 (key, nonce) 重用——已知明文即可伪造任一方向的数据包。现改为 HKDF 派生 c2s/s2c 两把方向密钥 + ChaCha20-Poly1305,包类型纳入认证;Ping/Pong 也走加密验证(此前伪造一个字节就能给别人的会话续命)

新增​

  • 前向纠错(tunnel.fec)与小包冗余(tunnel.tail_dup),默认关闭,按需开启对抗公网丢包
  • 隧道链路质量观测:客户端面板显示丢包率(五档:极好/高/中/差/极差)、乱序、抖动、延迟、纠错补回;服务端面板「活跃会话」弹窗新增每条隧道链路质量(管理员)
  • 隧道 MTU 协商与路径探测:按链路自动协商,装不下时自动下调,避免分片整包全损
  • UDP 收发批量化(tunnel.io_mode)与 Linux GRO/GSO 开关(默认关闭),可配置回退不必换二进制
  • 配置文件自带中文注释 + 模式版本号:升级后首次启动自动补全新增配置项(自定义值保留,原文件备份)

修复(客户端)​

  • 断开后点连接没反应、只能重启程序:连接流程自行退出(终态拒绝、创建网卡失败)后运行标记残留,以及「沿用已保存凭据」判据与界面清空凭据的行为不匹配——重连请求必被拒绝且报错一闪而过。现在出错后可直接重连,密钥留空即沿用已保存凭据,报错持续显示
  • 断开进行中点退出,路由清理被截断:退出现在等待断开清理完全结束,不再留下吸走玩家回包的残留路由;断开期间显示「正在断开…」
  • 退出程序后玩家全断:退出先停完隧道再关窗,Stop 立即关闭 socket 解除阻塞读
  • 升级强杀后老玩家全连不上:route add 幂等收编 + 启动时清扫残留的 /32 回程路由

性能​

  • 客户端「有人进服全服卡一下」的病根(route.exe 阻塞读循环)彻底移除:回程路由表 netip 化 + 热路径无锁,安装缓冲 8→32 包
  • 服务端会话表无锁快照、TUN 批量写、零分配封装/解密(每包 2~3 次堆分配 → 0)
  • 客户端空闲重握手 30s → 10s(NAT 换端口后最快 10 秒自愈)
客户端无需更新:本版本改动全部在服务端,pf-client 客户端代码零变化。现有 1.0.0
客户端可继续使用;重新发布的客户端压缩包仅随版本号刷新,内容与 1.0.0 一致。

修复​

  • 全代理突然失联、重启服务器才恢复的根因修复:服务器上的 ufw/宝塔等防火墙工具在
    reload 或增删规则时会整表清空 iptables,把隧道回程只在启动时装配一次的内核规则
    连带清掉——症状为控制面照常、玩家入站照常、所有透明代理静默失联、日志零痕迹。
    现由守护协程每 30 秒幂等校验,缺失自动补装,并在日志留下「规则何时被清」的时间戳
  • 隧道日志「丢弃源地址不匹配(疑似伪造)」不再误报:客户端 Windows 网卡的 IPv6 等
    非 IPv4 后台流量降为 debug 记录;真实源地址伪造嫌疑仍保持 warn
后退
顶部 底部