DS-Lite環境の自宅鯖でパルワールドのサーバーを建てた
はじめに
友人からパルワールドのサーバーを建てて欲しいとの話をもらい、建てたお話です。 なんと偶然(?)ゲームサーバーを建てられる環境があったのでやってみました。 パルワールドに限らず、MinecraftやValheimなどのサーバーをセルフホスト出来るタイプのゲームでも似たような解決が出来ると思います。
また、この記事を参考にされる場合(ならないかもしれないが)はあくまでも自己責任でお願いいたします。 ネットワークエンジニアなどその道のプロではないため理解不足などありましたら、Xまでご指摘いただけると嬉しいです!
DS-Lite環境によるサーバー公開の壁
タイトルにもある通り、自宅にあるサーバーでホストしたのですが、家の回線はDS-Lite方式(IPv4 over IPv6)です。 ざっくり言うと(間違っていたらすいません)、IPv4の通信をIPv6で包んでプロバイダまで運び、プロバイダ側のグローバルIPv4アドレスを複数の利用者で共用する方式で、自宅のルーターなどでは一般的なIPv4のポート開放が仕組み上できず、サーバーを建てても、グローバルIPv4を外から叩いた通信を自宅まで届けられません。
じゃあIPv6で直接通信すればいいじゃん!と一瞬思うのですが、友達の家がIPv4通信しか利用できない場合、IPv6で公開している我が家のサーバーとは直接通信を行うことができません。 また、契約しているプロバイダは、PPPoEとDS-Liteのどちらも対応しており、好きなように切り替えられるのですが、PPPoEだとゴールデンタイムなどのピーク時に回線速度が遅くなる傾向があったので嫌でした。(わがまま)
ではどうしたのか
中継用のサーバーを用意しました。 OCI(Oracle Cloud Infrastructure)では、少なくとも1GiBのRAMを持つ仮想マシン(VM)を無料枠で利用でき、固定のグローバルIPv4アドレスを割り振ることができます。 ※無料枠で利用できるリソースや空き状況はリージョンによって差があると思います。 OCIの登録方法やVMの建て方は省きますが、今回の構成としてはOCIの中継用VMから自宅のサーバーまでWireGuardトンネルを張った形になりました。
VMの中身ですが、iptablesを使って、グローバルIPv4のUDP 8211番ポートに来た通信を、WireGuardトンネル上の自宅サーバー(10.100.0.2:8211)へDNATしています。 かといって全リクエストを受け入れるのはあまりにも怖いので、OCI側で接続元IPを許可制にする形に。 友達にはAWSのcheckipでIPを確認してもらって、OCIの仮想クラウドネットワーク内のセキュリティ・リストのイングレス・ルールでそのIPからのUDP 8211番ポートへの通信だけを許可する感じ。 接続元のIPが変わった場合は、登録したIPもその都度変更する必要があります。(ちょっとめんどくさいが) ざっくりな図としては以下の通りです。
flowchart LR
Friend["友達のPC"]
subgraph OCI["Oracle Cloud Infrastructure"]
Rules["セキュリティ・ルール<br/>友達のIP・UDP 8211のみ許可"]
NAT["中継用VM<br/>iptablesでDNAT<br/>固定グローバルIPv4を割り当て"]
Rules --> NAT
end
Home["自宅サーバー<br/>Palworld"]
Friend -->|"UDP 8211"| Rules
NAT -->|"WireGuardトンネル"| Home
ちなみに、自宅側のパルワールドサーバーは、Pocketpairが配布している公式Dockerイメージを使用してDocker Composeで動かしています。 詳しい構築方法については、Palworld公式ドキュメントを参照してください。
遊びやすさと安全性のトレードオフ
仕事みてぇなタイトルになっちまった!
当たり前の話ですが、なんもせずIPを直で叩いてポンでアクセスできるってのはまぁ怖いもんです。
マイクラの公開サーバーを建てている方も、自宅の固定IPを露出したくないので、HAProxyなどで外部サーバーをかませているパターンも多いと思います。(主観)
特にPalworldの場合だと、PS5のユーザーがアクセスをするために公開サーバーリストに名前を載せる必要がありました。
ゲーム上に存在するサーバーにJoinするためのパスワードなどもありますが、あくまでもそれはアプリケーションレイヤ上での認証を行うものであって、UDP 8211番ポート自体に届く通信というのは遮断をしてくれません。UDP 8211番ポートへの通信を0.0.0.0/0からまるっと許可してしまうと、ゲームサーバーの脆弱性等を狙った攻撃を受ける可能性も捨てきれず…
実際に過去には、Minecraft Java Editionで使用されていたログライブラリ「Log4j」に脆弱性(CVE-2021-44228、通称Log4Shell)が見つかり、Minecraft公式からクライアントとサーバーの両方に対応を求める告知が出た事例もあります。ゲームサーバーを身内向けではあれど公開する身としては、ここらへんも気をつけておきたい部分です。
なので今回は友達向け少人数ということもあって、教えてもらったIPv4アドレスを手登録するという形に収まりました。 マジでケースバイケースだとは思いますが、今のところ問題なく遊べています。
参考資料
- RFC 6333 - Dual-Stack Lite
- OCI Always Freeリソース
- OCI パブリックIPアドレス
- Palworld Server Guide
- Palworld公式Dockerイメージ
- Java版MinecraftのLog4j脆弱性に関する公式告知
おわりに
ということでゲームサーバーをDS-Lite環境で公開してみた話でした。
ゲームサーバーを建てること自体はそこまで難しくないのですが、まぁセキュリティ周りとなると気をつける範囲が広いですね。
とりあえず仲間うちでパルワールドを遊べるようになったのでよし。 また何か書きます、それでは!