完全に趣味の話なので読者の参考になるかどうか分からないが、一応、記事化しておく。今回のテーマは、自宅で稼働させたゲームサーバーを外部に公開する方法の一例だ。クラウド上のVPSを接続待ち受け用のフロントエンドサーバー(ルーター)として利用し、ゲームの通信をWireGuard経由で自宅に転送する仕組みを紹介する。
先駆者を参考にする
以前、本コラムでTrueNASのゲームサーバー機能を紹介した際、最終的に、どのように外部からの接続を受け付けるのかが課題になると述べた。
今回は、この問いに対するひとつの回答を用意した。
どうするかというと、月額500円前後で借りられるVPSを接続先としてのフロントエンドサーバーとして構成し、ゲームサーバー本体は自宅に設置する方法を利用する。
Minecraftなどのサーバーを運営している先駆者のサイトを参考にすると、現状ゲームサーバーを自宅に設置する場合、どうやらこの方法が実用的なようなので、今回は参考にさせていただきつつ筆者宅の環境に合わせて応用した。この方式を見ると、確かに自宅のグローバルIPアドレスを公開する必要がない。
具体的には、自宅とVPSをWireGuardで接続し、VPSをフロントエンドサーバー(実質的にはルーター)として構成し、外部から受け付けたゲームの通信をWireGuard経由で自宅へと転送する。
ゲームでよく使われるUDP通信を転送するために、フロントエンドサーバーのVPS上ではLinuxのufw(iptables)を利用してルーターとして機能させ、VPSから自宅へ特定のポートをフォワードする形式としている。
もちろん、外部からの接続を受け付ける場合、どのような方法を採ったとしても、不正アクセスやDDoS攻撃などのターゲットになる危険性が常にあると考えておく必要がある。今回の方法は、こうした危険を緩和する方法のひとつではあるが、それでもリスクをゼロにはできないため、あくまでも自己責任において利用して欲しい。
なお、HTTP/HTTP接続の場合であれば、CloudflareのZero Trustを利用しつつ、リバースプロキシで自宅のサーバーを公開する手法が便利だ。ただし、Cloudflareではゲームなど任意のポートの転送はエンタープライズ向けプランの契約が必要になるため、今回はVPS上に転送の仕組みを自前で用意したことになる。
接続方法の全体像
具体的には、以下のような図の流れになる。冒頭で示した図は複雑なので、フロントエンドサーバーを1台にしたシンプルな例で紹介する。プレイヤーが接続する流れを追うように、次の図の下から上への流れを5ステップで解説していく。
STEP1:ゲームから接続
ここでは、インターネット上のプレイヤーがゲームを起動し、ドメイン名で接続する方法を想定している。ドメイン名を指定すると、DNSサーバーに接続先のサーバーのIPアドレスが問い合わせされ、その回答によってゲームからの接続が行われる。ここまでは、ごく普通。
STEP2:フロントエンドサーバーに接続
接続先として通知されるのは、ゲームサーバー本体のIPアドレスだが、今回は自宅のゲームサーバーのIPアドレスはプライベートIPとなるうえ、自宅の回線のグローバルIPアドレスも公開しない方向で設定する。
では、接続先としてどのアドレスを通知するのかというと、クラウド上のVPSで構成したフロントエンドサーバーのグローバルIPアドレスだ。このフロントエンドサーバーで、接続を受け付ける。
このサーバーは、月額500円前後となるCPU1コア、RAM512MBの最低限の構成で、今回はUbuntu 20.04を利用した。
仕組みもシンプルだ。インストールするソフトウェアは、後述するWireGuardのみで、あとはLinuxの機能のみを利用して、ゲームの通信を転送するだけの役割で機能させる。
VPSサーバーとして必要なのは、ネットワークの設定で、ゲームが利用するポートを開けておくことだ。
STEP3:ufwでフォワード
さて、VPSがゲームから接続を受け付けても、フロントエンドサーバーにはゲームサーバー本体はインストールされていないので、プレイを開始できない。今回のVPSの役割は「転送」だけなので、転送のための設定をしておく。
具体的には、外部からゲームの通信、たとえばMinecraft Bedrock版なら19132/udpの接続を受け付けると、これをLinuxのファイアウォール機能であるufw(実質的にはiptables)の設定を利用して、自宅に設置してあるゲームサーバー本体へと転送する。
ufwの設定は何段階かある。ひとつはゲームの通信を許可することだ。これはコマンドで簡単に設定できる。
続いて、転送を許可する。設定ファイル2つを開き、IPv4フォワードを許可しておく。
最後に「/etc/ufw/before.rules」にゲーム通信の転送用の設定を追加しておく。Destination NATを利用し、例えばMinecraft Bedrock版の19132/udpが宛先になっている通信の転送先として自宅のゲームサーバーのプライベートIPアドレスを指定しておく。
上記画面は、多数のゲームのテストを実施したため、複数のルールが記載されているが、例えば、Minecraft Bedrock版だけなら、以下のように19132/udpに対してPREROUTINGとPOSTROUTINGで対になるルールを記載しておけばいい。
# NAT
*nat
-F
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p udp –dport 19132 -j DNAT –to-destination 192.168.100.182:19132
-A POSTROUTING -p udp –dport 19132 -j MASQUERADE
#COMMIT
COMMIT
なお、同様にゲーム用通信の転送には、UDPの転送が可能なNginxのReverse Proxy(stream)を利用する方法が紹介されることもあるが、筆者が試した限りではNginxのstreamではパラメーターを数パターン調整しても、一定間隔でUDP通信が切れる現象(ゲームだと数十分のプレイごとにほぼ1回切断される)が発生し、結局改善策を見つけられなかった。
そのため、今回のようにシンプルにUDP通信を転送する方式を採用した。
STEP4 WireGuardで自宅へ
もちろん、このままでは転送された通信が自宅のゲームサーバーに届かない。ゲームサーバーのIPアドレスはプライベートIPであるうえ、自宅のルーターでゲーム用のポートも開放していないので、外部から自宅側に通信が入れない。
このため、自宅とVPSの間をVPNで接続する。この接続には、今回、高速かつ軽量なWireGuardを利用した。
また、VPS側をサーバーとして構成することで、自宅→VPSの方向で接続するようにしてある。これにより、自宅側はポート開放一切不要で、回線もIPv6 IPoE環境のMAP-EやDS-Liteなどの環境でも問題なく接続できるようになっている。
実際の設定は簡単だ。まず、VPSでWireGuardの接続を受け付けられるように51820/udpの接続を許可しておく。VPSのファイアウォール設定に加え、今回はLinux側でufwも利用しているので、ufwでも接続を許可しておく(STEP3で解説した画面参照)。
続いて、VPSと自宅のゲームサーバーにWireGuardをインストールし、接続用の設定ファイルをコピーする。
WireGuardの設定には、以下のツールを利用すると便利だ。Webサイトにアクセスし、接続したい自宅側のサーバーの台数や接続先のVPSのドメイン名などを指定するだけで設定ファイルを自動生成できる。
▼WireGuardの設定ファイル生成ツール
Wireguard Config Generator
生成されたファイルは、若干、手直しが必要だ。サーバー側は「AllowedIPs」の部分に自宅側のゲームサーバーのIPアドレスを記載しておく。これで、Server用をVPSの「/etc/wireguard/wg0.conf」として保存しておく。
同様にClient用の設定ファイルも、自宅のゲームサーバーの「/etc/wireguard/wg0.conf」として保存し、それぞれでWireGuardを起動すればVPNで接続される。クライアント側は、接続を維持するためにKeepaliveの設定を入れている。
VPS費用が安く収まるのがメリット
結局、筆者宅では冒頭で触れたようにVPSを複数台利用するなどしているため複雑化してしまったが、シンプルに構成すれば、回線種別を問わず、自宅のネットワークを公開することなしに、月額500円前後のVPSのみでゲームサーバーが公開できることになる。
もちろん、冒頭でも触れように、間にクッションがいくつかあるだけで、インターネット側と自宅がつながっていることに変わりはないためリスクはあるが、それでも直接自宅のポートを開放するなどの方式よりは安全に利用できるはずだ(DDoS対策となると、複数VPS併用などの工夫は必要)。
もちろん、VPSでゲームサーバーを運用する手もある。自宅サーバー愛好家に、こうした指摘はまったく意味がないが、一応、言い訳としては、ゲーム用のVPSはスペックが高く、費用も高くなるので、安く運用できるというメリットはある。