BLOG

BDS運営者向け NetherNet対応ガイド:26.60からの変更点、ポート、HTTPS化、サーバー間転送

2026年10月28日 ・ 約15分

結論から

BDS(Bedrock Dedicated Server)を運営している人向けに、先に結論を書きます。

  • 1.26.60(2026年10月27日リリース)から、BDSはNetherNet専用になりました。 transport=raknetにしても起動はしますが、「NetherNetのみ対応」というエラーバナーが出ます。RakNetを前提にした運用は、もう続けられません。
  • ポートは「TCP 1つ + UDP 1つ」で考えるのが基本です。 1.26.60.6の実機では、TCP 19132(シグナリング)とUDP 19132(ゲーム本編)の2つを開ければ足りました。形はRakNet時代と同じです。ただし、TCPだけでなくUDPも開ける必要があります。
  • 初回の「このサーバーを信頼しますか」画面は、HTTPS化でなくせます。 ただしBDS単体ではHTTPSにできません。ドメインと有効な証明書を持つリバースプロキシ(nginxなど)でTLSを終端し、BDSには平文HTTPで渡す構成にします。
  • サーバー間転送(transferPlayer)は、hostname+port(IP+ポート)で行います。 自前のBDS同士の転送は、この方法で成功しました。netherNetId(UUID)は、自前のBDSでは使えませんでした。

この記事は、T6NetWork運営者が実機で確かめた内容と、公式の資料をもとにしています。確度は次のように書き分けます。

  • [公式]:BDS同梱のマニュアルや、Mojangの公式ガイドに書かれていること
  • [実機確認]:運営者が実際に動かして確かめたこと
  • [報告]:他の利用者の報告
  • [未検証]:まだ確かめられていないこと

1. 1.26.60で何が変わったか

NetherNet専用になった

NetherNetは、WebRTCをもとにした新しい通信方式です。1.26.60.6(2026-10-27)で次のことを確認しました。[実機確認]

設定 BDSの挙動
transport=nethernet TCP 19132で待ち受け、シグナリングサービスへ自動でサインインする
transport=raknet 起動はでき、RakNetのUDPも開くが、「NetherNetのみ対応」のエラーバナーが出る
transportに不正な値 Unknown Transport Layer Type ...というエラーを出し、既定のNetherNetで起動を続ける

26.60のクライアントが、RakNetのBDSに実際に繋げるかどうかは、確認できていません。1.26.52.3ではraknetでも繋がったという報告がありますが、GeyserMCやAternosは26.60でRakNet接続が終わると案内しています。[報告]

なお、NetherNetは26.40から順次展開され、BDSの既定が切り替わったのは26.50、という案内もあります(GeyserMCの記事より)。公式のリリースノートでは確認していないので、時期は目安として読んでください。

UDPの既定が「1ポート共有」になった

ここが、運用に一番効く変更です。[公式][実機確認]

  • 1.26.52.3まで:クライアントごとにOSの一時ポートを使うため、人数分のUDP範囲(例:約100人で49152-49251)を開ける必要があった
  • 1.26.60から:server-udp-ports=19132が既定で、全クライアントが1つのUDPポートを共有する

注意点が2つあります。

  1. 公式マニュアルの本文には「未設定ならOSの一時ポートから割り当てる」とも書かれていて、表の既定値(19132)と食い違っています。ただ、既定のserver.propertiesにはserver-udp-ports=19132が有効な行として入っていました。[実機確認]
  2. 共有ポートでも、BDSはそのPCのすべてのIPアドレス(LAN、VPN、IPv6など)でUDP 19132を開きます。ファイアウォールでは、公開したい経路だけを許可してください。[実機確認]

複数のクライアントが同時に同じポートを共有できるかは、1人でしか試していないため、まだ確かめられていません。

2. ポート(TCP/UDP)の考え方

NetherNetは、役割の違う2つの通信でできています。

  • TCP(server-port):最初の取り決め(シグナリング)。平文のHTTPでGET /v1/joinなどを受け付ける
  • UDP:ゲーム本編の通信。取り決めのあと、クライアントとサーバーが直接やり取りする

公式マニュアルは、インターネットに公開するならserver-portの手前にリバースプロキシを置くことを推奨しています。プロキシを通すのはシグナリング(TCP)だけで、ゲーム本編のUDPは直接つながります。[公式]

最低限の開放

TCP 19132   ← シグナリング
UDP 19132   ← ゲーム本編(1.26.60以降の既定)

DockerやNATの背後で動かす場合は、とくに注意が必要です。従来のUDP 19132だけを公開していて、NetherNetにしたら繋がらなくなった、という報告があります(itzg/docker-minecraft-bedrock-serverのissue #673)。[報告]

server-udp-portsの書式(1.26.60.6の公式マニュアル)

モード 例 意味
共有ポート 19489 全員でUDP 19489を共有
公開:ローカル 29489:19489 公開側29489をローカル19489へ
範囲 19400-19500 接続を範囲内に分散
範囲+マッピング 21200-21300:19400-19500 両側の長さは同じにする
公開IP付き 12.19.20.18:19489:19489 IP:公開:ローカル。両方のポートが必須

いちばん多いつまずき:ホスト名は使えない

NATやトンネルの背後で、外部公開用のマッピングを書くときは、**IPアドレスのリテラルで書きます。ホスト名は使えません。**ホスト名にすると、サーバーは起動し、GET /v1/joinにも応答しますが、クライアントはDoorというエラーで接続に失敗します。[報告]

外部からの接続でDoorが出たという相談は、他のコミュニティでも見つかります。まず、この2点を疑ってください。

  1. server-udp-portsのマッピングが、ホスト名やコンテナ内部のIPになっていないか
  2. UDPがファイアウォールやルーターで塞がれていないか

3. 初回の信頼確認画面をなくす(HTTPS化)

なぜ画面が出るのか

NetherNetでは、サーバーが自分の長期の鍵(keys/server_identity_key.pem)で、本人であることを示します。平文HTTPで繋いだ場合、クライアントは「初回信頼(TOFU)」方式で、鍵を初めて見たときにプレイヤーへ確認を出します。

一方、有効なTLS証明書のあるHTTPSで繋いだ場合は、TLSが信頼の根拠になり、確認画面は出ません。[公式]

Mojang公式ガイド(§5.2)の要点は次の通りです。

  • TLSなら、プレイヤーに初回の確認を出さない
  • 平文HTTPなら、初回に確認を出し、以降は同じ鍵を黙って受け入れる
  • HTTPSでも、サーバーの署名(a=identity)がない接続は拒否される(BDSは自動で付けるので、設定は不要)

BDS単体ではHTTPSにできない

BDS同梱のマニュアルに、TLS証明書やHTTPSの設定項目はありません。そこで、手前にリバースプロキシを置きます。

プレイヤー ─HTTPS(TCP 19132)→ nginx(TLS終端) ─HTTP→ BDS
プレイヤー ◀══ UDP(ゲーム本編) ══▶ BDS

なお、公式ガイドの§5.2は「リバースプロキシでTLSを終端した場合も、HTTPSの信頼として扱われるか」までは書いていません。ですが、後で紹介する実機の構成では、確認画面が出ませんでした。[実機確認]

手順

① ドメインと証明書を用意する

  • IPアドレス単独には、通常のTLS証明書を付けられません。ドメインが必要です
  • Let's Encryptなどで証明書を取る(certbotの例)
sudo certbot certonly --standalone -d play.example.com \
  --deploy-hook "systemctl reload nginx"

nginxには、中間証明書を含むfullchain.pemを使ってください。cert.pemだけだと、検証に失敗するクライアントがあります。証明書は90日で切れるので、sudo certbot renew --dry-runで、自動更新が動くことを確認しておきましょう。

② BDSを内部用のポートに移す

公開側のTCP 19132をnginxが使うので、BDSのserver-portは別の値にします。

transport=nethernet
server-port=<内部用のポート>

③ nginxでTLSを終端する

server {
    listen 19132 ssl;
    listen [::]:19132 ssl;
    server_name play.example.com;

    ssl_certificate     /etc/letsencrypt/live/play.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/play.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:<内部用のポート>;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Connection "";
        proxy_read_timeout 60s;   # BDSの応答を待つので、短くしすぎない
    }
}

④ ファイアウォール

公開するのは、TCP 19132とUDP(19132か、設定した範囲)です。BDSの内部用ポートは、外から届かないようにします。

⑤ 動作確認

curl -s https://play.example.com:19132/v1/join

サーバー情報のJSONが返れば、シグナリングは通っています。最後に、ゲームでドメイン名を入力して接続し、確認画面が出ずに入れれば成功です。

HTTPSにしない場合の軽減策

  • serveridentity saveで鍵を保存しておくと、再起動しても同じ身元として扱われ、確認はプレイヤーごとに初回の1回だけで済みます(鍵がないと、起動のたびに出ます)
  • 複数のサーバーで同じ鍵を共有すると、全サーバーを通して、確認は1回で済みます。[公式]
  • シグナリングを外部サービスに任せるNXS規格(例:Warden)もあります。サーバー側のTCPポートは不要になりますが、MOTDや人数の表示は定期更新になります(GeyserMCの記事より)

4. サーバー間転送は「IP+ポート」で行う

transferPlayerの2つの指定方法

@minecraft/server-adminのtransferPlayer()は、プレイヤーを別のBDSへ転送する関数です。

import { transferPlayer } from "@minecraft/server-admin";

// 自前のBDS同士なら、こちら
transferPlayer(player, { hostname: "example.com", port: 19132 });

// 参考:NetherNetのID指定(UUID形式必須)
transferPlayer(player, { netherNetId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" });

実機で分かったこと

運営者が、BDSを2台(転送元と転送先)起動して確かめた結果です。[実機確認]

宛先に渡したもの 結果
{ hostname: "127.0.0.1", port: 19133 }(転送先BDSのIPとポート) 成功(転送先のログで接続とスポーンを確認)
実在しないUUID クライアントがInitialConnection-102(シグナリングが届かない)で失敗
転送先BDSの起動ログのSession ID 同じくInitialConnection-102
フレンドのセッションのPmsgId InitialConnection-95(届くが返事がなくタイムアウト)
hostnameにnethernet:<ID>を入れる 「無効なIPアドレスです!」で拒否

つまり、自前のBDSは、netherNetIdとして引ける公開IDを持っていないようです。netherNetIdが指す宛先は、Realmsのような、Microsoftのメッセージング網に登録されたものだと考えられますが、これは推測です。netherNetIdで転送が成功する宛先は、まだ確認できていません。

そのほかの注意点です。

  • netherNetIdがUUID形式でないと、InvalidArgumentErrorがすぐに投げられます。UUID形式なら、実在しなくてもエラーにならず、転送が試行されてから失敗します。BDSは転送先の実在を確認しません。[実機確認]
  • クライアントの失敗画面にあるInitialConnection-<番号>は、Mojang公式のプロトコルドキュメントにある切断理由(DisconnectFailReason)の並び順と一致しました。BDSのログには、クライアントが宛先に繋げたかどうかは出ないので、原因の切り分けにはこの番号が役立ちます。[実機確認]
  • IP+ポートでの転送でも、転送先を初めて見るプレイヤーには、信頼確認が出る可能性があります。転送先でもHTTPSのドメインを使うか、全サーバーで同じ識別鍵を共有しておくと、この確認を減らせます。
  • スクリプトの実行には、ワールドで「Beta APIs」実験の有効化が必要です。manifest.jsonの@minecraft/serverのバージョンも、BDSのビルドごとに違います(合わないとスクリプトが読み込まれません)。開発中は、content-log-console-output-enabled=trueにしておくと、読み込みの失敗に気づけます。

@minecraft/server-adminの型定義は、確認した4つのバージョン(1.26.60-preview.25から1.26.70-preview.21まで)で同一でした。transferPlayerのNetherNet関連に、新しい変更は見つかっていません。

5. T6NetWorkの実例:VPSのnginx + frp

T6NetWorkでは、自宅で動かすBDSを、中継用のVPS(ConoHa)のnginxとfrp経由で公開しています。BDS自体は平文HTTPのままで、HTTPSはVPSが受け持ちます。[実機確認]

プレイヤー ─HTTPS(TCP 19132)→ VPSのnginx(証明書あり)
                                   └ TLSを外し、frpのトンネル経由で自宅のBDSへ
ゲーム本編のUDPは、frpで直接つなぐ

やったことは次の4つです。

  1. 証明書:VPSでLet's Encryptの証明書を発行(play.t6server.net)。更新後にnginxを再読み込みする仕組みも入れました
  2. nginx:streamモジュールのssl_prereadで、TLSかどうかを見分けます。TLSの接続は、TLSを外して中継先へ。平文HTTPの接続は、そのまま中継先へ渡します。同じ19132番ポートで、HTTPSと平文HTTPの両方を受けています
  3. UDP:server-udp-portsの外部側を、VPSの公開IPのリテラルにして、frpでつなぎました(ドメインではなくIP)
  4. ファイアウォール:frpが使う中継用のポートは、外から届かないよう閉じました

結果として、2つのサーバーに入ったとき、どちらも信頼確認の画面は出ませんでした。

外から見た状態も確認しています。https://play.t6server.net:19132/v1/joinが200でサーバー情報を返し、応答ヘッダはServer: nginx、TLSは1.3でした。

この構成のUDPは、1.26.52.3までの方式(範囲指定)に合わせたものです。1.26.60以降の共有ポート1つなら、frpの転送も1ポートで済む可能性がありますが、この構成ではまだ試していません。

同じ形で、HTTPSと平文HTTPを同じポートで受ける場合は、1つ注意があります。BDS側から見たクライアントのIPがすべてプロキシのIPになるため、IPごとのリクエスト制限が効かなくなります。必要なら、PROXYプロトコルや、stream側の接続数制限を検討してください。

6. 周辺ツールの状況

  • playit:エージェントv1.1.0(2026-10-27、正式版)のリリースノートに、NetherNet対応の追加があります。ただし、サポート文書はまだ「RakNetに切り替える」案内のままで、無料で使えるかは確認できていません。HTTPSは使えない見込みなので、初回の確認画面は出ると考えられます。[未検証]
  • GeyserMC:transportにbothがあり、RakNetとNetherNetを併用できます。BDS本体は、新旧の併用はできません。
  • Cloudflareのプロキシ:対応するポートが限られており、19132は含まれないはずです。使うなら、DNSのみ(プロキシなし)にします。[未検証]

まとめ

  • 1.26.60からBDSはNetherNet専用です。transport=nethernetを前提にしてください
  • 必要なポートは、基本的にTCP 19132とUDP 19132です。NATやトンネルの背後では、server-udp-portsの外部側をIPリテラルで書きます。ホスト名は使えません
  • 初回の信頼確認は、ドメイン+有効な証明書のリバースプロキシでTLSを終端すると出なくなります。HTTPSにしない場合は、識別鍵を保存し、全サーバーで共有します
  • サーバー間転送は、transferPlayerの**hostname+port**で行います。netherNetIdは、自前のBDS同士では使えませんでした

26.60はリリースされたばかりです。UDP共有ポートの同時接続や、26.60クライアントとRakNetの関係など、まだ確かめられていない点もあります。分かり次第、追記していきます。

参考

※この文章はClaude AIによって作成されました。

← ブログ一覧へ