事故報告

服務異常的原因、處理與現況 ・ 共 1 份

速通伺服器從桌機搬到 hina-server,並解決 iOS 與行動網路玩家無法加入的問題。已由玩家實際連線驗證。

為什麼以前可以、現在不行

以前基岩版玩家連的是 Java 生存伺服器上的 Geyser 轉接器,它用的是舊的 RakNet 連線方式。9 月 26 日改用 Mojang 官方的基岩版伺服器(BDS)後,連線方式換成 NetherNet,原本的設定就不夠用了。

項目以前(到 9/26)現在
伺服器Geyser(接在 Java 伺服器上)官方基岩版伺服器 BDS 1.26.52
連線方式RakNet:一個 UDP 端口直接連NetherNet:先用 TCP 握手,再另外協商 UDP 連線
路由器要轉發UDP 19132 一條TCP 19132 + UDP 19136–19155
遊戲用的 UDP 端口固定 19132預設隨機,要手動固定並公告公網 IP
iOS 從外部連可以握手要加密(TLS),BDS 做不到,要靠代理
raknet — The traditional Bedrock UDP transport. The server listens directly on server-port (IPv4) and server-portv6 (IPv6), and clients connect to that address and port. This is the mode used by releases prior to the NetherNet transport being made the default.

RakNet 是舊版的連線方式,玩家直接連一個 UDP 端口。NetherNet 成為預設之前的版本都用它,也就是以前 Geyser 那種連法。

BDS 隨附說明文件(bedrock_server_how_to.html)・Transport
nethernet (default) — A WebRTC-based transport. The server listens on a single dual-stack TCP socket on server-port for an HTTP-based signaling handshake, then negotiates a UDP connection with each client that carries the gameplay traffic.

NetherNet 現在是預設:先在 TCP 上用 HTTP 握手,再替每位玩家另外協商一條 UDP 連線傳遊戲資料。所以路由器只轉 UDP 已經不夠。

BDS 隨附說明文件・Transport
By default, the NetherNet transport allocates UDP ports for client connections from the operating system's ephemeral range, which is fine for most LAN and outbound-friendly deployments but is not always suitable for servers that sit behind a firewall or NAT.

遊戲用的 UDP 端口預設是隨機的,在區網沒問題,放在路由器(NAT)後面就不一定連得上。這就是行動數據玩家連不上的原因,要用 server-udp-ports 固定端口。

BDS 隨附說明文件・UDP port configuration for NetherNet
Because the NetherNet handshake on server-port speaks HTTP/TCP, it is recommended to put a reverse proxy (for example nginx, HAProxy, or a managed edge service) in front of server-port

官方建議在握手端口前面放反向代理。我們用 Caddy 做這件事,順便提供 iOS 需要的 TLS 加密。

BDS 隨附說明文件・Transport
Generated keys are not saved automatically, this will cause the server to have a different identity each time it is started, causing players to have to re-accept server trust.

沒保存身分金鑰的話,每次重啟都會換身分,玩家就得重新信任伺服器。

BDS 隨附說明文件・Server Identity
NETHERNET — What it means: There was a multiplayer connection error.

官方對 NETHERNET 錯誤碼只說是「多人連線錯誤」,沒有指出原因,所以這次要靠封包紀錄找出來。

Minecraft Help・Named Error Code Troubleshooting(NETHERNET)

說明文件的設定表仍列出 transport=raknet。這版 BDS 設成 raknet 時主控台會顯示「NetherNet is the only supported transport type」,我們當時據此認定不能改回 RakNet;Mojang 的 bug 回報 BDS-23108 與 playit.gg 都說設成 raknet 仍可連線,所以 9/27 另開一台 raknet 測試伺服器實測:伺服器會回應 RakNet 的探測,但實際客戶端加入時出現 KELP 錯誤,伺服器端完全沒有玩家連線紀錄。在我們的環境下 RakNet 確實不能用,NetherNet 加 TLS 代理是唯一可行的做法。iOS 在公網上一定要 TLS 這一點,官方文件沒有寫,是這次從封包紀錄比對出來的;國外也有相同的回報(見下方參考資料)。

對照:reizoko 的白話說明

reizoko 把改變比喻成:以前的 RakNet 像單純的「營業窗口」,現在的 NetherNet 像複雜的「相親仲介」。下面逐點對照官方文件與這次的實測結果。

  • 正確

    NetherNet 改用 WebRTC 技術

    官方文件原文就是「A WebRTC-based transport」。

  • 正確

    從「單向盲寄」變成「雙向交換名片」:伺服器要把自己的 IP 交給玩家,但它只知道內網 IP,所以要手動寫死公網 IP

    官方文件寫明 server-udp-ports 不加 IP 時會「advertise the host's own addresses」,也就是內網位址。我們就是在設定裡寫入「公網 IP:19136-19155」解決的。

  • 正確

    從「固定一扇門」變成「先敲門再找隨機暗道」:先 TCP 19132 握手,再開隨機 UDP,必須手動釘死

    官方文件寫的是 ephemeral range(隨機端口)。原文舉例的 19133 其實是 server-portv6 的預設值;我們實際固定的是 19136–19155 一整段。

  • 部分成立

    缺乏穿透工具:沒有內建 STUN 探測真實 IP

    BDS-23108 裡有使用者分析 ICE 收集不到外部候選位址(reflexive candidate),和這個說法一致;但 BDS 程式裡確實有 STUN 相關程式碼,我們也沒測過拿掉 IP 前綴時它能不能自己發現,所以只能說「實務上需要手動填」。

  • 未證實

    微軟推 NetherNet 是為了主機與 Realms 的封閉生態

    官方文件沒有說明動機,這段是推測。

  • 原文遺漏

    (原文沒提到)iOS 在公網上一定要加密握手

    這是 iOS 連不上的直接原因:TLS 失敗後 iOS 不會改用一般 HTTP。只修 IP 和 UDP 設定解決不了,要靠 TLS 代理。

參考資料

  • 巴哈姆特 Minecraft 哈啦板

    2026-09-27 查詢:找不到討論 NetherNet 或這次改版連線問題的文章,現有的基岩版開服教學都還是 RakNet 時代(只轉 UDP 19132)的做法。

  • Mojang bug 回報 BDS-23108:Transport type "nethernet" renders server inaccessible

    影響 1.26.51.1 與 1.26.52.3,截至 9/26 仍未確認。回報者指出改回 raknet 仍可連線(雖然主控台報錯),但我們實測不成立;也有人手動設定 server-udp-ports 公網 IP 解決,這點和我們一致。

  • itzg/docker-minecraft-bedrock-server #680

    9/19 回報:iOS 26.51 客戶端無法完成 NetherNet 的 TLS 握手,BDS 回傳 7 位元組的 TLS 警告(handshake failure)後斷線,錯誤碼 InitialConnection-13。和我們封包紀錄看到的完全相同。

  • playit.gg:Minecraft Bedrock NetherNet

    說明新版預設改為 NetherNet,暫時可在 server.properties 設 transport=raknet 繞過,並稱這只是權宜之計。我們在 1.26.52.3 實測這個方法失敗(客戶端顯示 KELP)。

如何連線

伺服器位址hina-tw.ddns.net請用網域,不要用 IP
連接埠19132基岩版預設值

結果

速通伺服器hina-server原本的世界、紀錄、玩家資料與伺服器身分都已還原,玩家不需要重新信任伺服器。
iOS 從外部連線已修復加上 TLS 代理後,iOS 用網域可以加入。
行動數據連線已修復遊戲 UDP 固定在 19136–19155 並轉發,電信商的 CGNAT 不再擋住連線。
速通面板正常改從 hina-server 讀取資料,不外洩玩家 xuid/pfid。
測試用乾淨伺服器已移除刪除前已打包保存。
桌機舊速通伺服器停用排程已停用,資料夾只留作參考。

連線路徑

握手與遊戲資料走不同的路。握手(TCP)先經過 Caddy 用正式憑證加密(Caddy 也在 hina-server 上,聽 19131,由路由器把外部 19132 轉過去);遊戲資料(UDP)直接送到速通伺服器。

玩家iOS / PC / 手機路由器port forwardCaddyTLS 解密 :19131hina-server速通 BDSTCP 19132HTTPUDP 19136–19155(遊戲資料)

找到的問題 6 項

  1. iOS 從外部連不上

    封包比對顯示:基岩版客戶端會先用 TLS 握手,BDS 一律拒絕。PC 和「iOS 連區網 IP」會改用一般 HTTP 繼續;iOS 連公網位址時不會改用 HTTP,直接放棄。

    解法Caddy 以 hina-tw.ddns.net 的 Let's Encrypt 憑證接收 TLS,再轉給 BDS。所以外部玩家要用網域連線。

  2. 行動數據(CGNAT)連不上

    沒設定 server-udp-ports 時,遊戲資料用隨機 UDP 端口,只能靠「打洞」,電信商的多層 NAT 會讓它失敗。

    解法把 UDP 固定在 19136–19155 並公告公網 IP,路由器轉發這段端口。

  3. 伺服器偶爾啟動了卻連不進去

    strace 顯示 BDS 綁定 19132 時得到「端口已被使用」卻不報錯,就這樣沒開連線端口繼續跑。原因是前一次的連線殘留(TIME_WAIT,約 60 秒)。

    解法啟動前先等殘留連線清掉,再確認端口有開;失敗最多重試 3 次,不會無限重開。

  4. 伺服器清單顯示不出資訊

    enable-lan-visibility=false 時,BDS 回給客戶端的伺服器資訊是空的。

    解法速通伺服器開啟 enable-lan-visibility=true。

  5. 每次重啟玩家都要重新信任伺服器

    沒有保存身分金鑰時,BDS 每次啟動都換一個新身分。

    解法金鑰保存在 server/keys/,並沿用桌機原本那把。

  6. 路由器規則重複

    同一個端口有兩三條規則,其中一條是這次腳本誤加的。

    解法整理成兩條:TCP 19132 → Caddy(hina-server:19131)、UDP 19136:19155 → hina-server。

給玩家

遊戲內指令
  • /start 開始倒數
  • /hina:reset [種子] 換新世界
  • /hina:timer 看目前時間
連線有問題時
  • 確認用的是 hina-tw.ddns.net,不是 IP
  • 確認遊戲已更新到最新版
  • 截圖錯誤畫面並記下時間,回報給管理員

需要注意

公網 IP 變動

伺服器每 5 分鐘檢查一次公網 IP,改變時會公告並自動重啟。重啟那一下在線的玩家需要重新連線。

自動更新

每 6 小時檢查 Minecraft 伺服器新版本,有新版會提前 60 秒公告再更新重啟。手機商店的版本可能晚幾天才跟上。

沒有自動備份

刻意不備份:速通世界本來就會被 /reset 替換。舊世界會在 /reset 時封存最近 5 個。