はじめに
身内で久しぶりにMinecraftをしようとなったのでホストを引き受けたのですが、現在の家は無料ネットなのでグローバルIPが使えず、一般的な手法であるポート開放での待ち受けが出来ません。
そこで、ゲームサーバー本体はローカルで動かしつつ、安いVPSを契約して接続の窓口とし、手軽なVPNサービスであるTailscaleを経由してパケットをローカルに飛ばす、という手法を用いて公開を試みます。
この方法であれば、グローバルIP無しでサーバーが公開できる他、自宅のIPを晒さなくて良い、ローカルのポートを開放しなくて良いというメリットもあります。
探せば似た内容の記事がわんさか出てくるのですが、同じ設定では動作しないことが多かったので備忘録も兼ねて記事にしました。
運用環境
- VPS側
- Ubuntu24.04 LTS
- CPU:1core Mem:1GB
多くのVPS業者で契約可能な最低スペックです。ここで動かすのはTailscaleだけなのであまりスペックはいらないですが、参加する人数やゲームによっては不足するので、適宜合った性能のものを契約してください。プレイの快適さに直結するため、可能であれば日本リージョンを選ぶとよいです(海外リージョンだと通信が長距離往復する兼ね合いで非常にラグがあります)。
参考までに同時接続5~6人程度のMinecraftサーバーであればこの性能で十分です。
- local側
- Ubuntu24.04 LTS
- CPU:お好みで Mem:お好みで
実際にゲームサーバーを動かす環境です。性能は動かしたいサーバーの要件に合わせてください。この記事では解説を省きますが、Taiscaleが使えるのであればWindowsなどでも問題ありません。
今回はベアのサーバーにUbuntuをそのままインストールしていますが、ローカルIPが割り当てられる環境であればVMやWSL上の環境でも手順は同じです。
構築の流れ
1. VPS側:初期設定
外部へ公開するサーバーになるので、ある程度セキュリティは固めておきたい所。公開に必要な設定以外は省きますが最低限鍵認証の設定やsshポートの変更はしておいてください。
また、VPS側でセキュリティポリシーが設定できる場合はそちらも変更するとよいでしょう。
今回は以下のように設定にしています。ssh用に自宅IPからtcp/2020、Minecraftサーバー用に全てのIPからtcp/25565を受け付ける設定です。
2. VPS/local側:Tailscaleを導入
まずはTailscaleを導入しましょう。以下の2行を実行すると、ログイン用のurlが払い出されるのでアクセスしてログインします。これをVPSとlocalの両方で行います。
$ curl -fsSL https://tailscale.com/install.sh | sh
$ sudo tailscale up
To authenticate, visit:
https://login.tailscale.com/a/1d12345678abc #<-このurlにアクセス
追加が完了したら、このページで2台のサーバーが追加されていることを確認します。問題なさそうなら、それぞれのサーバーのtailscale側IP(画像の赤枠の箇所)を控えておいてください。
最後に、2台のサーバー間で疎通ができるか確認します。双方でpingを実行して帰ってきたら成功です。
$ ping 100.x.x.x # 先ほど控えたlocal側のtailscale IP
$ ping 100.x.x.x # 先ほど控えたVPS側のtailscale IP
3. VPS側:iptablesの設定
VPSで待ち受けたゲームの通信パケットをローカル側に流す設定です。iptablesを使います。
# iptables-persistentで、コマンドによる設定を永続化
$ sudo install iptables-persistent
# インストール中に以下のような画面が出るので、Noを選択してください
# コマンド用にシェル変数を定義
$ GAMEIP=100.xxx.xxx.xxx # 先ほど控えたtailscaleのlocal側IP
$ VPSIP=100.xxx.xxx.xxx # 先ほど控えたtailscaleのVPS側IP
$ PORT=25565
$ sudo iptables -t nat -A PREROUTING -p tcp \
--dport $PORT -j DNAT \
--to-destination $GAMEIP:$PORT
$ sudo iptables -t nat -A POSTROUTING -p tcp \
-d $GAMEIP --dport $PORT \
-j SNAT --to-source $VPSIP
$ sudo iptables -A FORWARD -p tcp \
-d $GAMEIP --dport $PORT \
-j ACCEPT
$ sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# 上記の設定を永続化
$ sudo netfilter-persistent save
4. 接続確認
ここまで出来たら、あとはゲームサーバーを起動するだけです。
ローカルにMinecraftサーバーを立て、VPSのグローバルIPで参加したところ無事サーバーに入れました。
遅延もそれほどなく、少人数であれば快適に動作しています。一時間に一回程度切断されるのが若干不便ですが、nginxのリバプロ等を用いた転送方法よりも安定しているように感じました。
なお、この方法ではFWにiptablesを使用するのですが、ufwを併用すると設定が勝手に消されてしまう事がありました。OS側でFWを使う場合は全てiptablesで設定してしまったほうが早そうです。