VPSを使って「マインクラフト」などの自宅ゲームサーバーを安全に公開する方法【イニシャルB】

INTERNET Watch

自宅に設置したゲームサーバーを外部公開する一例。筆者が現在、運用している例。フロントエンドサーバー2台構成で、1台が落ちても対応できるようにしてみた

 完全に趣味の話なので読者の参考になるかどうか分からないが、一応、記事化しておく。今回のテーマは、自宅で稼働させたゲームサーバーを外部に公開する方法の一例だ。クラウド上の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:フロントエンドサーバーに接続

VPSを用意し、ゲームからの接続を受け付けられるように構成する

 接続先として通知されるのは、ゲームサーバー本体のIPアドレスだが、今回は自宅のゲームサーバーのIPアドレスはプライベートIPとなるうえ、自宅の回線のグローバルIPアドレスも公開しない方向で設定する。

 では、接続先としてどのアドレスを通知するのかというと、クラウド上のVPSで構成したフロントエンドサーバーのグローバルIPアドレスだ。このフロントエンドサーバーで、接続を受け付ける。

 このサーバーは、月額500円前後となるCPU1コア、RAM512MBの最低限の構成で、今回はUbuntu 20.04を利用した。

 仕組みもシンプルだ。インストールするソフトウェアは、後述するWireGuardのみで、あとはLinuxの機能のみを利用して、ゲームの通信を転送するだけの役割で機能させる。

 VPSサーバーとして必要なのは、ネットワークの設定で、ゲームが利用するポートを開けておくことだ。

VPSのファイアウォール画面でWireGuardのポートやゲームのポートを許可しておく

STEP3:ufwでフォワード

ゲームから受け取ったUDP通信をフロントエンドサーバーが自宅サーバーへと転送する。なお、今回、IPv6は不使用

 さて、VPSがゲームから接続を受け付けても、フロントエンドサーバーにはゲームサーバー本体はインストールされていないので、プレイを開始できない。今回のVPSの役割は「転送」だけなので、転送のための設定をしておく。

 具体的には、外部からゲームの通信、たとえばMinecraft Bedrock版なら19132/udpの接続を受け付けると、これをLinuxのファイアウォール機能であるufw(実質的にはiptables)の設定を利用して、自宅に設置してあるゲームサーバー本体へと転送する。

 ufwの設定は何段階かある。ひとつはゲームの通信を許可することだ。これはコマンドで簡単に設定できる。

ufwのenableでWireGuardやゲームの通信を通過させる

 続いて、転送を許可する。設定ファイル2つを開き、IPv4フォワードを許可しておく。

「/etc/default/ufw」ファイルで「DEFAULT_FORWARD_POLICY=“ACCEPT”」を設定する

「/etc/ufw/sysctl.conf」ファイルで「net/ipv4/ip_forward=1」を設定する

 最後に「/etc/ufw/before.rules」にゲーム通信の転送用の設定を追加しておく。Destination NATを利用し、例えばMinecraft Bedrock版の19132/udpが宛先になっている通信の転送先として自宅のゲームサーバーのプライベートIPアドレスを指定しておく。

「/etc/ufw/before.rules」の末尾の「COMMIT」の下にNAT用のルールを追加する

 上記画面は、多数のゲームのテストを実施したため、複数のルールが記載されているが、例えば、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で自宅へ

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

「Wireguard Config Generator」でWireGuardの設定ファイルを簡単に生成できる

生成された設定をサーバーとクライアントにファイルとして保存すればOK

 生成されたファイルは、若干、手直しが必要だ。サーバー側は「AllowedIPs」の部分に自宅側のゲームサーバーのIPアドレスを記載しておく。これで、Server用をVPSの「/etc/wireguard/wg0.conf」として保存しておく。

フロントエンドサーバー(VPS)側の「/etc/wireguard/wg0.conf」ファイル

 同様にClient用の設定ファイルも、自宅のゲームサーバーの「/etc/wireguard/wg0.conf」として保存し、それぞれでWireGuardを起動すればVPNで接続される。クライアント側は、接続を維持するためにKeepaliveの設定を入れている。

自宅のゲームサーバー(VPS)側の「/etc/wireguard/wg0.conf」ファイル

「sudo systemctl enable wg-quick@wg0」でサービスとして登録し、「sudo systemctl start wg-quick@wg0」で起動する。「sudo wg show」で接続状態を確認できる

STEP5:自宅ゲームサーバーに接続

WireGuardから自宅のゲームサーバーまでを接続

 前のステップで自宅とフロントエンドサーバーがVPN接続されたため、フロントエンドサーバーから自宅のゲームサーバーのプライベートIPアドレスとの間で通信が可能になる。

 要するに、ゲームの通信(19132/udp宛て通信)が「game.smznode.net」→「43.206.x.x」→(ufwでWireGuard側に転送)→「192.168.100.182」と転送されるわけだ。

 これで、無事に自宅のゲームサーバーに接続されることになる。

VPS費用が安く収まるのがメリット

 結局、筆者宅では冒頭で触れたようにVPSを複数台利用するなどしているため複雑化してしまったが、シンプルに構成すれば、回線種別を問わず、自宅のネットワークを公開することなしに、月額500円前後のVPSのみでゲームサーバーが公開できることになる。

 もちろん、冒頭でも触れように、間にクッションがいくつかあるだけで、インターネット側と自宅がつながっていることに変わりはないためリスクはあるが、それでも直接自宅のポートを開放するなどの方式よりは安全に利用できるはずだ(DDoS対策となると、複数VPS併用などの工夫は必要)。

 もちろん、VPSでゲームサーバーを運用する手もある。自宅サーバー愛好家に、こうした指摘はまったく意味がないが、一応、言い訳としては、ゲーム用のVPSはスペックが高く、費用も高くなるので、安く運用できるというメリットはある。

Source