Project Zomboid サーバーを DDoS 攻撃から守る

公開日 更新日 読了時間 37 分

専用の Project Zomboid サーバーが本当に必要とするポートはどれか、servertest.ini のどのディレクティブが重要か、接続時の Mod 照合がなぜ攻撃の的になるのか、そしてどの攻撃規模から手前のネットワークでのフィルタリングしか効かなくなるかを解説します。

Project Zomboid サーバーを DDoS 攻撃から守るには、まず攻撃側が何を狙って撃ってくるのかを知る必要があります。専用サーバーが占有する UDP ポートはちょうど 2 つ、16261 と 16262 で、どちらもネットワークに開けておかなければ誰も参加できません。本記事は、いざというときに役立つ順番で進めます。まず、追加費用なしでこの 10 分のうちにご自身でできること、次に、その対策が技術的にどこで限界を迎えるか、最後に、その手前のネットワークで何が起きる必要があるかです。

本記事の記述はすべて、Debian 12、Debian 13、Ubuntu 22.04 LTS、Ubuntu 24.04 LTS 上で動く専用サーバー(Steam のアプリケーション 380870)を前提としており、ビルド 41 でもビルド 42 でも変わりません。設定ファイルは servertest.ini で ~/Zomboid/Server/ に置かれ、ワールドデータは ~/Zomboid/Saves/Multiplayer/ にあります。コマンドは root 向けに書かれているため、一般ユーザーの場合は先頭に sudo を付けてください。

攻撃がいま進行中の場合:servertest.ini は変更せず、サーバーも再起動しないでください。まずは測定値を保存します(第 9 項)。攻撃が終わってからでは、もう残っていません。再起動はさらに、サーバーがワールドを読み込む時間を余分に奪います。攻撃側が狙っているのは、まさにその時間です。

Project Zomboid サーバーが DDoS 攻撃の標的になる理由

Project Zomboid は、死が取り消せず、ワールドが何か月も続いていくゲームです。危険な場面の途中で接続が切れたときの代償は、ほかのほぼどのジャンルよりも大きくなります。キャラクターは失われ、ワールドはそれを覚えているからです。だからこそ、障害そのものが武器になります。20 時の攻撃は固定したコミュニティを狙い、しかも失うものが最も大きい場面を狙ってきます。

さらに、攻撃そのものに費用がかからず、技術も要りません。その世界で booter や stresser と呼ばれる受注型の攻撃サービスは、数回のクリックで IP アドレスとポートに向けられ、Project Zomboid では標的が常に同じです。16261 UDP です。BAN したプレイヤーともめている人や、競合するコミュニティを運営している人は、知識もまとまった金額も必要としない道具を手にしていることになります。

加えて、ゲームサーバーは自分の住所を公開しなければなりません。servertest.ini に Public=true と書かれていればサーバーはゲーム内のブラウザーに現れ、Steam に接続しているサーバーはいずれにせよ Steam のサーバーブラウザーから見えます。つまり問題は、攻撃側がお使いの IP アドレスを見つけるかどうかではなく、そこに撃たれたときに何が起きるかだけです。

技術面でいちばん厄介な点は最後に来ます。ゲームトラフィックはすべて UDP で流れます。UDP には要求できるような接続確立の手順がなく、どのパケットもそれ単体で成立し、送信元アドレスは偽装できます。つまり攻撃側は、お使いのサーバーに参加する必要も、正しく話しかける必要もなく、負荷をかけられます。DDoS 攻撃が具体的に何であるかは、記事 DDoS 攻撃とは何か で解説しています。

Project Zomboid サーバーが本当に必要とするポート

専用の Project Zomboid サーバーが必要とする開放ポートはちょうど 2 つ、16261 UDP と 16262 UDP です。ゲームの公式なポート一覧に 3 つ目はありません。servertest.ini では 2 つの独立したディレクティブとして記述され、2 つ目のポートは 1 つ目から自動的に決まるわけではありません。

DefaultPort=16261
UDPPort=16262
SteamPort1=8766
SteamPort2=8767
RCONPort=27015
RCONPassword=

役割分担は明確です。16261 UDP はゲームトラフィックと接続確立を担い、サーバーブラウザーの問い合わせに応答します。16262 UDP はクライアントの直接接続用のポートです。1 つ目が欠けていれば誰もサーバーを見つけられず、2 つ目が欠けていれば、プレイヤーには一覧の項目が見えているのに中へ入れません。このゲームで最も有名なエラーメッセージ、ポート 16262 が閉じているという表示は、まさにここから来ています。

ポート プロトコル 用途 servertest.ini のディレクティブ インターネットから到達できるか
16261 UDP ゲームトラフィック、接続確立、サーバーブラウザーの問い合わせ DefaultPort=16261 はい、必須
16262 UDP クライアントの直接接続 UDPPort=16262 はい、必須
8766 と 8767 UDP サーバーの Steam 接続 SteamPort1、SteamPort2 いいえ。公式の必須一覧にあるのは 16261 と 16262 だけ
27015 TCP RCON によるリモート操作 RCONPort=27015 いいえ。ご自身のアドレスだけに限定する
22 TCP オペレーティングシステムへの SSH アクセス servertest.ini には書かれていない 制限する

よく問題になる点が 2 つあります。第一に、サーバーインスタンス 1 つごとに、空いている UDP ポートが 2 つ必要です。同じマシンで 2 つ目のワールドを動かす場合は、そのために 2 つ目の組、たとえば 16274 と 16275 を割り当て、両方の値を 2 つ目のインスタンスの servertest.ini に書きます。第二に、SteamPort1 と SteamPort2 は 8766 と 8767 として設定ファイルに書かれていますが、これはサーバーの Steam 接続に属するもので、ゲームトラフィックではありません。これらを開けるのは、開けなければお使いのサーバーが Steam の一覧に出てこない場合だけにしてください。念のためで開けてはいけません。

費用をかける前に自分でできること

この節が最も長いのは意図的です。きちんと設定されたサーバーは、どこに置かれていようと、小規模から中規模の攻撃を自力で耐えます。ボリューム型攻撃を引き受けてくれるわけではありませんが、安価な攻撃を無効にし、いざというときに推測ではなく数値を残してくれます。

1. 現状把握:実際に何が待ち受けているか

ルールを 1 つ書く前に、お使いのサーバーが外に何を提供しているかを確認します。推測せず、実際に見てください。

ss -lntup

注目するのはローカルアドレスの列です。0.0.0.0:16261 と [::]:16261 は「インターネット全体から到達できる」、127.0.0.1:27015 は「ローカルのみ」で、開放は不要という意味です。初期値に頼らず、結果をご自身の設定と突き合わせてください。

grep -E "^(DefaultPort|UDPPort|SteamPort1|SteamPort2|RCONPort|Public|Open|MaxPlayers|MaxAccountsPerUser)=" ~/Zomboid/Server/servertest.ini

攻撃側からの見え方は、外部からのポートスキャンで分かります。Project Zomboid は UDP しか使わないため、そのためには UDP スキャンが必要です。TCP だけのスキャンでは、ゲームポートはまったく表示されません。

nmap -Pn -sU -p 16261,16262,8766,8767 YOUR.SERVER.IP.ADDRESS
nmap -Pn -p- --min-rate 1000 YOUR.SERVER.IP.ADDRESS

2. 16261 と 16262 だけを開けたままにする

外に向けた開放は 2 つで足り、それ以外は制限するか、そもそも公開しません。UFW では次のようになります。自分自身を締め出さないよう、この順番どおりに実行してください。

ufw allow 22/tcp comment "SSH"
ufw allow 16261/udp comment "Project Zomboid"
ufw allow 16262/udp comment "Project Zomboid 直接接続"
ufw allow from 203.0.113.10 to any port 27015 proto tcp comment "RCON"
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

203.0.113.10 はご自身のアドレスに置き換えてください。有効化するときの順番が、自分を締め出すかどうかを決めます。その順番と復旧手段は記事 自分を締め出さずに UFW ファイアウォールを設定する にあります。それでも締め出してしまった場合、KernelHost の KVM ルートサーバーと専用サーバーなら、ゲスト側のネットワークに依存せず動作するカスタマーエリアの VNC コンソールからシステムに入れます。

データベースと付随サービスについて一言。Project Zomboid はどちらも必要としません。ゲーム以外で 0.0.0.0 で待ち受けているものは、以前の導入作業か管理パネルの名残であり、127.0.0.1 にバインドするか、停止するかのどちらかです。

3. ポート 27015 の RCON をインターネットから外す

RCON はサーバーのリモート操作機能で、Project Zomboid では 27015 TCP で動きます。出荷時の servertest.ini には RCONPassword= が値なしで書かれています。RCON を使う場合は長いランダムなパスワードを設定してください。このプロトコルは暗号化せずに送るため、到達できる RCON ポートに弱いパスワードが付いていると、攻撃トラフィックを 1 パケットも使わずにサーバーを丸ごと渡してしまいます。

安全な方法は、ポートをそもそも外に開けず、SSH のポートフォワーディング経由で到達することです。そのあとはローカルの 127.0.0.1:27015 と通信します。

ssh -N -L 27015:127.0.0.1:27015 root@YOUR.SERVER.IP.ADDRESS

RCON が不要なら、パスワード欄は空のまま、ポートは閉じたままにします。到達できないサービスは、総当たりもフラッドも受けません。

4. 送信元アドレスごとにパケットレートを制限する

小規模な攻撃や作りの粗いボットには、送信元アドレスごとの上限が効きます。2 つのゲームポートは隣り合っているため、範囲を指定したルール 1 つで足ります。

iptables -I INPUT -p udp --dport 16261:16262 -m hashlimit --hashlimit-name pz_udp --hashlimit-mode srcip --hashlimit-above 400/sec --hashlimit-burst 600 -j DROP
iptables -L INPUT -n -v

このルールは、同じ送信元アドレスが毎秒 400 パケットを継続して超えた時点で UDP パケットを破棄します。この値は出発点であって、絶対の正解ではありません。同じ街に 30 人が集まっているサーバーは、マップの別々の場所に 4 人がいるサーバーよりはるかに多くのトラフィックを生みますし、厳しすぎる設定は自分のプレイヤーを追い出します。まずは平常時を 1 週間測り、そのうえで上限をピーク値の数倍に置いてください。

注意点が 2 つあります。iptables のルールだけでは再起動で消えるため、Debian と Ubuntu では次のように保存します。

apt-get install -y iptables-persistent
netfilter-persistent save

UFW を使っている場合、こうしたルールは /etc/ufw/before.rules に書きます。そうしないと、次の ufw reload で消えてしまいます。iptables -L INPUT -n -v の一致カウンターで、そのルールにそもそも届いているかを確認してください。カウンターが 0 のままなら、置き場所が違います。

5. 接続追跡の負荷を下げる

見落とされがちな詰まりどころがカーネルにあります。接続追跡は UDP でも送信元アドレスとポートごとにエントリーを作るため、偽装した送信元からのフラッドは数秒でこのテーブルを埋めます。あふれると、サーバーは正規のパケットまで破棄し、ログには「nf_conntrack: table full」と出ます。現在値と上限は次のコマンドで確認できます。

sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max

Project Zomboid のゲームトラフィックに状態の追跡は必要ありません。UDP には状態がないからです。そのため、2 つのゲームポートをテーブルの外に置けます。

iptables -t raw -I PREROUTING -p udp --dport 16261:16262 -j NOTRACK

これでカーネルの負荷がはっきり下がります。重要なのは、このルールが当てはまるのはサーバーがパケットを直接受け取っている場合だけということです。その手前でアドレス変換を行っている場合、たとえばポートを転送するコンテナ構成では、設定してはいけません。戻り方向が対応づけられなくなるからです。

6. 参加とスロットを固める

次の数行は費用がかからず、通常の参加経路から来るものすべてに効きます。

Password=A-LONG-RANDOM-PASSWORD
Open=false
MaxAccountsPerUser=1
MaxPlayers=32
DenyLoginOnOverloadedServer=true

Password は共通のサーバーパスワードで、個々のプレイヤーのアカウントとは別物です。Open=false は、管理者が事前に作成したアカウントだけが参加できるという意味で、これがこのゲームの許可リストです。MaxAccountsPerUser は、1 人の Steam ユーザーがお使いのサーバーで作れるアカウント数を制限します。初期値の 0 は無制限を意味します。MaxPlayers は初期状態で 32 で、それを超える設定については、マップの読み込みが悪くなり同期ずれが起きるとドキュメントが明確に警告しています。

ここでの落とし穴は PingLimit です。このディレクティブは、指定したミリ秒の遅延を超えたプレイヤーを切断し、初期状態では 0、つまり無効です。攻撃を受けると、まず自分のプレイヤーの遅延が上がります。つまり厳しい値は、引き留めたい相手をそのままキックします。この制限は無効のままにするか、余裕を持たせて設定してください。

そして、はっきりさせておくべきことが 1 つあります。許可リストが守るのはゲームのロジックで、回線ではありません。お使いのサーバーをあふれさせる攻撃側は、そもそも参加する気がありません。そのパケットは拒否されますが、それでも届いてはいます。まさにそこが問題です。

7. 接続時の Mod 照合は、サーバーで最も高くつく 1 秒

Project Zomboid は接続時にパスワードだけを調べるわけではありません。サーバーの Mod リストは servertest.ini の 2 行に書かれます。WorkshopItems には数値の Workshop ID、Mods には Mod の読み込み ID が入り、どちらもセミコロン区切りです。参加時にクライアントはこの一覧を照合し、足りない Workshop の内容を Steam 経由で自動的に取得し、そのあとでようやくワールドデータの送信を受けます。さらに DoLuaChecksum=true の場合、サーバーはゲームファイルのチェックサムを比較し、自分のものと合わないファイルを持つクライアントを切断します。

攻撃側にとって興味深いのはまさにこの点です。作業が実際のプレイ参加より前に発生するからです。接続の試行 1 回ごとに、バージョン、チェックサム、Mod リスト、マップデータのための計算時間がサーバーから奪われます。最終的に拒否される試行でも同じです。Mod リストが長ければ、その試行 1 回ごとの代償が高くなります。そのため参加フラッドは、大きく改造されたサーバーのほうが未改造のサーバーより効きますし、必要な帯域幅はボリューム型攻撃のごく一部で済みます。これに対して、ゲームには 2 つのブレーキが組み込まれています。

DenyLoginOnOverloadedServer=true
LoginQueueEnabled=true
LoginQueueConnectTimeout=60

DenyLoginOnOverloadedServer は、サーバーが過負荷のあいだ新しいログインを拒否し、進行中のセッションまで巻き込んで落ちることを避けます。LoginQueueEnabled は参加者を同時に処理せず待ち行列に入れ、LoginQueueConnectTimeout は参加にかけられる時間を決めます。初期値は 60 秒で、指定できるのは 20 から 1200 です。

対処を間違えやすい細部を 1 つ添えます。Linux サーバーには、DoLuaChecksum が誤検知を起こしてプレイヤーを入れなくなる、記録された不具合があります。そのため検査を無効にする運用者がいます。理解できる判断ですが、ゲームファイルを書き換えたクライアントを遠ざける仕組みを 1 つ失うことになります。無効にせざるを得ない場合は、サーバーパスワード、許可リスト、アカウント数の上限をその分だけ厳しく設定してください。

8. サーバーリスト、UPnP、自分のアドレス

ここは願望ではなく事実で考えたほうが得です。お使いの IP アドレスは秘密にできません。Public=true はサーバーをゲーム内のブラウザーに表示し、Steam に接続しているサーバーはドキュメントによればいずれにせよ Steam のサーバーブラウザーから見えます。つまり Public=false は、新しいプレイヤーからの見つけやすさを失わせるだけで、ご自身を見えなくするわけではありません。

Public=true
PublicName=私の Zomboid サーバー
UPnP=false
server_browser_announced_ip=

UPnP は初期状態で true で、サーバーがインターネットのゲートウェイで自らポート開放を設定しようと試みます。レンタルサーバーにそのようなゲートウェイはなく、この試行は空振りに終わるため、無効にすべきです。server_browser_announced_ip は空のままにします。例外は、お使いのサーバーが複数のアドレスを持ち、そのうちの 1 つで意図的に表示させたい場合だけです。専用の保護 IP に切り替えるときには、まさにこの項目が再び必要になります。

どの設定よりも効くのは 2 つの習慣です。生の IP アドレスをご自身でどこにも公開しないこと、つまり Discord のチャンネルにもプロジェクトのページにも書かないことと、プレイヤーにはホスト名を渡すことです。アドレス変更でよくあるのが古い DNS レコードです。以前のアドレスを指す A レコードが 1 つ残っていると、どんな変更も無意味になります。

9. すべてが平常に動いているうちに測る

最も重要なのは、ほとんど誰も事前にやらない手順、つまりすべてが静かなうちに基準値を作っておくことです。平常時の値がなければ、障害のあとで毎秒 4 万パケットが多かったのか、それとも単に土曜の夜だったのかを判断できません。apt-get install -y vnstat sysstat で測定は常に走り続けます。障害の最中は、4 つのコマンドで足ります。

sar -n DEV 1 10
ip -s link show eth0
tcpdump -ni eth0 "udp port 16261 or udp port 16262" -c 200 -q
journalctl -u zomboid --since "-15 min" | tail -50

最初の 2 つはインターフェースのパケットレートと破棄パケットのカウンターを、3 つ目はトラフィックの短い標本を、4 つ目はサーバーが systemd のサービスとして動いている場合にそのメッセージを表示します(サービス名は合わせて変更してください)。tcpdump では必ず -c で件数を区切ってください。全負荷の状態での取得は、すでに過負荷のサーバーにさらに負荷をかけます。測定値の読み方は サーバーで DDoS 攻撃を検知する にあります。

ここまでの対策が限界を迎える地点:帯域幅とパケットレート

ここからは、どの設定ファイルでも解決できない部分です。これまでの対策はすべてお使いのサーバー上、つまり回線の末端で動きます。ファイアウォールのルールが判断するのは、すでにケーブルを通り終えたパケットです。破棄はできますが、送られなかったことにはできません。

一度計算してみてください。一般的なゲームサーバーは 1 Gbit/s の回線につながっており、これは毎秒 125 メガバイトです。誰かがそれより多く送った時点で、回線は埋まります。2 つ目の指標はパケットレートで、こちらは帯域幅より早く効くことがよくあります。64 バイトの小さなパケットなら、1 Gbit/s には毎秒約 149 万パケットが入りますが、通常のサーバーのカーネルが破棄を始める前に処理できるのは、CPU とネットワークカードによりますがそのうち数十万にすぎません。つまり回線の 3 分の 1 も埋めない攻撃で、お使いのサーバーを止められます。運用者にはこれが「使用率はまったく高くなかったのに、それでも全部落ちた」という形で見えます。

項目 値
1 Gbit/s をバイトに換算 毎秒 125 メガバイト
64 バイトのパケットが 1 Gbit/s に入る数 毎秒約 149 万パケット
そのうちサーバーのカーネルが処理できる数 毎秒数十万パケット
コミュニティのゲームサーバーに対する一般的な攻撃規模 5 から 50 Gbit/s
KernelHost でフィルタリングした、ゲームサーバーへの UDP フラッド 112.2 Gbit/s 超
KernelHost のサーバーに対する記録上最大の攻撃 毎秒 4150 万パケット超で 473.4 Gbit/s 超

ゲームサーバーのコミュニティに対する一般的な攻撃は 5 から 50 Gbit/s、つまり通常の回線の 5 倍から 50 倍です。これに効くローカルの設定はありません。ボリューム型攻撃は、サーバーの手前のネットワークで終わらせる必要があります。

ゲームサーバーへの DDoS 攻撃に KernelHost が用意している対策

すべてのサーバーに標準で含まれる常時保護

KernelHost のすべてのサーバーには、3.2 Tbps の DDoS 基本保護が標準で含まれています。有効化も注文も設定もなしに常時動いており、Advanced DDoS Protection で強化することもできます。

  • 標準装備:フランクフルトにおける 3.2 Tbps の Arbor リアルタイムフィルタリング。 UDP フラッド、SYN フラッド、ICMP フラッドといった一般的なフラッド攻撃や、リフレクション攻撃、増幅攻撃を、サーバーの直前で検知し、パケット単位で破棄します。
  • Advanced DDoS Protection 利用時:グローバルなスクラビングネットワークにおける最大 17 Tbps の緩和能力。 非常に大規模な攻撃は、データセンターに届く前に、発生源の近くで除去されます。さらに、特化したプロファイルが個々のゲームを狙った攻撃をフィルタリングします。

決定的な性質が 2 つあります。保護は常時動いており、攻撃を受けてから反応する必要がありません。つまり、最初の数分だけサーバーが落ちている、ということが起きません。そしてヌルルーティングは使いません。お使いの IP アドレスはネットワークに残り、破棄されるのは有害なパケットだけです。IP アドレスをネットワークから外す事業者は、ご自身にとって攻撃側と同じ結果をもたらします。Advanced DDoS Protection が専用のプロファイルでどのゲームとプロトコルに対応しているかは ゲームサーバーの DDoS 対策をリアルタイムで にまとめています。

継続的に攻撃されるプロジェクト向けの Advanced DDoS Protection

プロジェクトによっては、たまたまではなく、狙って何週間も攻撃されます。そのために Advanced DDoS Protection があり、月額 50.00 EUR、PrePaid、最低利用期間なし、初期費用なしで利用できます。グローバルなスクラビングネットワークにおける最大 17 Tbps の緩和能力が加わり、制御できる範囲も大きく広がります。

  • 専用の保護 IP をフランクフルトの中核から割り当て、お使いのサーバーを当社のネットワーク内で切り替えます。ご自身の側で作り直す作業はありません。新しいアドレスは、プレイヤーがサーバーを見つける場所に書き換えるだけです。
  • ポートとプロトコルごとに自分で管理できる保護ルールをカスタマーエリアで設定できます。16261 と 16262 の UDP で何を許可するかをご自身で決め、それ以外は閉じたままです。そのためにチケットを書く必要はありません。
  • 変更はリアルタイムで反映されます。そのため、攻撃が進行している最中に調整できます。
  • 用途に合った保護プロファイル。主要なゲームには既製のプロファイルがあり、改造したアプリケーションや独自のアプリケーションではポートとプロトコルごとにルールをご自身で設定します。Project Zomboid はゲームトラフィックがすべて隣り合う 2 つの UDP ポートを通るため、とくに正確に絞り込めます。

2 つの段階の比較

項目 標準で含まれる DDoS 常時保護 Advanced DDoS Protection
料金 すべてのサーバープランに含まれ、追加料金なし 月額 50.00 EUR、PrePaid
フィルタリング能力 フランクフルトにおける 3.2 Tbps の Arbor リアルタイムフィルタリング 最大 17 Tbps のグローバルなスクラビングと、フランクフルトにおける 3.2 Tbps の Arbor リアルタイムフィルタリング
IP アドレス お使いのサーバーの IP アドレス 追加の専用保護 IP
ルールセット 一般的なフラッド攻撃を自動でフィルタリング、設定は不要 カスタマーエリアでポートとプロトコルごとの独自ルール
変更 自動で追従する リアルタイムで反映され、攻撃の最中でも可能
ヌルルーティング なし なし
契約期間 サーバープランに連動 PrePaid、最低利用期間なし、解約予告期間なし、初期費用なし

一般的なフラッド攻撃に対しては、標準で含まれる基本保護と、きちんとした設定を組み合わせれば十分です。Advanced DDoS Protection は、誰かが個人的な問題として攻撃してくる場合への答えです。

よくある失敗とその対処

「プレイヤーに、ポート 16262 が閉じているというメッセージが出る」:これは攻撃ではなく、開放が足りていません。サーバーには 16261 UDP と 16262 UDP の両方が必要で、しかも UDP のルールとして必要です。同じ番号に対する TCP の開放では何も起きません。ufw status verbose と外部からの UDP スキャンで、本当に両方が開いているかを確認してください。

「IP アドレスを変えたのに、2 時間後にまたオフラインになった」:攻撃側は新しいアドレスを、古いアドレスと同じ情報源から手に入れています。たいていはサーバーリストの項目、ステータス表示付きの Discord ボット、あるいは古い DNS レコードです。Project Zomboid では変更に追加の代償があります。クライアントはマップデータをアドレスとポートごとにローカルへ保存し、Zomboid/Saves の下に 123.45.0.12_16261_... のような名前のフォルダーを作ります。変更後は、探索済みのマップを各プレイヤーがサーバーから読み直します。つまりアドレス変更は、追加の費用を伴う時間稼ぎであって、解決ではありません。

「iptables のルールが効かない」:よくある原因は 3 つです。ルールが UFW のチェーンの後ろにあって到達しない、前回の再起動で消えていた(この場合は netfilter-persistent save か /etc/ufw/before.rules への記述が助けになります)、あるいは攻撃がボリューム型で、ルールはすでに埋まった回線の上で正しく動いている、のいずれかです。iptables -L INPUT -n -v で一致カウンターが増えているか確認してください。

「プレイヤーが参加時に弾かれるのに、サーバーは普通に動き続けている」:これはほぼ常に攻撃ではなく照合です。原因は、クライアントとサーバーのバージョン差、Workshop の項目の欠落や古さ、あるいは合わないチェックサムです。クライアントはたいてい、一致しない Mod を表示します。WorkshopItems と Mods を 1 行ずつ突き合わせてください。

「数分ごとにラグスパイクが出て、そのあと元に戻る」:これは、プレイヤーが嫌気が差してやめるまでだけ走る短い攻撃の、典型的な形です。まず CPU 負荷ではなく、ネットワークのカウンターを見てください。sar -n DEV 1 10 と破棄パケットのカウンターに異常がなければ、攻撃ではなく負荷でした。同じセルに集まりすぎたプレイヤー、負荷の重い Mod、あるいは Java のインスタンスに割り当てたメモリーの不足です。

「これまで使っていた事業者に IP アドレスを遮断された」:それがヌルルーティングです。事業者はそれで自分のネットワークを守りますが、ご自身にとっての結果は攻撃の成功と同じで、多くの場合そのあと数時間続きます。判断に迷うときは、フィルタリングなのかヌルルーティングなのかを尋ねてください。その答えは、どんなハードウェアの仕様よりも可用性を左右します。

「tcpdump で見ても、おかしなところがない」:手前のネットワークですでにトラフィックが除去されている場合、サーバーには何も届かないのが当然です。フィルタリングが機能しているときの通常の姿です。逆に回線が飽和していると、測定に使おうとした SSH セッションさえ届かないことがあります。その場合は、カスタマーエリアの VNC コンソールを使ってください。

まとめ

  • 専用の Project Zomboid サーバーが必要とする開放ポートはちょうど 2 つです。16261 UDP(DefaultPort)と 16262 UDP(UDPPort)で、どちらも servertest.ini の独立したディレクティブとして書かれています。
  • RCON は 27015 TCP で動き、初期状態ではパスワードなしで登録されています。このポートは開いたインターネットに置くものではなく、ご自身のアドレスだけに限定するか、閉じておくものです。
  • 接続時の Mod 照合が最も高くつく箇所です。バージョン、チェックサム、Workshop のリスト、マップデータは計算時間を食い、拒否される試行 1 回ごとにも発生します。これに対するゲーム内蔵のブレーキが DenyLoginOnOverloadedServer と参加の待ち行列です。
  • サーバーパスワード、Open=false、MaxAccountsPerUser=1 はゲームのロジックを守ります。飽和した回線には、これらの設定はどれも効きません。
  • 物理的な限界は動きません。1 Gbit/s は毎秒 125 メガバイトで、64 バイトのパケットなら毎秒約 149 万パケットです。ゲームサーバーに対する一般的な攻撃は 5 から 50 Gbit/s です。
  • ボリューム型攻撃は、サーバーの手前のネットワークで終わらせる必要があります。KernelHost では、フランクフルトにおける 3.2 Tbps の Arbor リアルタイムフィルタリングが、追加料金なしで、ヌルルーティングなしで動いています。Advanced DDoS Protection を利用すると、グローバルなスクラビングネットワークにおける最大 17 Tbps の緩和能力が加わります。
  • 継続的に攻撃される場合は、Advanced DDoS Protection でフィルタリングをご自身で制御できます。専用の保護 IP、ポートとプロトコルごとのルール、リアルタイムで反映される変更が、月額 50.00 EUR で使えます。

お使いのサーバーをすでに KernelHost で動かしている場合、フィルタリングは何もしなくても有効です。それでも異常に気づいたときは サポートチケット を開いてください。お使いの IP アドレス向けにフィルタールールを調整します。攻撃が進行中の場合は、WhatsApp の緊急チャット +43 650 8209883 でもご連絡いただけます。

よくあるご質問

Project Zomboid サーバーがいまオフラインです。これは DDoS 攻撃でしょうか?
まず CPU 負荷ではなく、インターフェースのパケットレートを見てください。sar -n DEV 1 10 で毎秒のパケット数とバイト数が、ip -s link show eth0 で破棄パケットのカウンターが分かります。サーバー自体はほとんど働いていないのに受信パケットが平常時の値を大きく超えているなら、攻撃です。ネットワークのカウンターに異常がないのに動作が重いなら、原因はゲーム内の負荷です。同じセルに集まりすぎたプレイヤー、負荷の重い Mod、あるいは Java のインスタンスに割り当てたメモリーの不足です。
Project Zomboid サーバーでは、どのポートを開ける必要がありますか?
ちょうど 2 つ、16261 UDP と 16262 UDP です。servertest.ini では DefaultPort=16261 と UDPPort=16262 として書かれており、この 2 つは独立した設定です。2 つ目のポートは 1 つ目から自動的に決まりません。どちらも UDP として開放する必要があり、同じ番号に対する TCP のルールでは何も起きません。同じマシンで動かす追加のサーバーインスタンスには、それぞれ空いている UDP ポートの組が必要です。RCON 用のポート 27015 TCP は、開いたネットワークに置くものではありません。
ポート 16262 は何のためにあり、なぜクライアントは閉じていると表示するのですか?
16262 UDP はクライアントの直接接続用のポートで、16261 UDP はゲームトラフィックを担い、サーバーブラウザーの問い合わせに応答します。16261 だけが開いていると、プレイヤーには一覧の項目が見えているのに中へ入れず、クライアントはポート 16262 が閉じていると表示します。原因はほぼ常に、ファイアウォールかルーターで UDP の開放が足りていないことで、攻撃ではありません。外部からの UDP ポートスキャンで両方のポートを確認してください。
ポート 8766 と 8767 は必要ですか?
これらは servertest.ini に SteamPort1=8766 と SteamPort2=8767 として書かれており、サーバーの Steam 接続に属します。公式な必須ポートの一覧にあるのは 16261 UDP と 16262 UDP だけです。したがって 8766 と 8767 を開けるのは、開けなければお使いのサーバーが Steam のサーバーリストに出てこない場合だけにし、念のためでは開けないでください。開いているポートが 1 つ増えるたびに、撃たれる面が 1 つ増えます。どの開放にも、ご自身で説明できる理由があるべきです。
Project Zomboid の RCON ポート 27015 はリスクですか?
はい、開いたインターネットに置かれた時点でリスクです。RCON はサーバーの完全なリモート操作で、Project Zomboid では 27015 TCP で動き、暗号化せずに送ります。出荷時の servertest.ini では RCONPassword に値がありません。RCON を使うなら長いランダムなパスワードを設定し、このポートはご自身のアドレスにだけ開放するか、SSH のポートフォワーディング経由で到達してください。RCON が不要なら、ポートは閉じたままにします。
接続時の Mod 照合は、なぜサーバーを攻撃されやすくするのですか?
作業が、誰かが実際にプレイするより前に発生するからです。参加時にサーバーはゲームのバージョン、ゲームファイルのチェックサム、WorkshopItems と Mods による Mod リストを比較し、クライアントは足りない Workshop の内容を自動的に取得し、そのあとでようやくマップデータの送信を受けます。試行 1 回ごとに計算時間がかかり、サーバーが最後に拒否する試行でも同じで、Mod リストが長ければ 1 回ごとの代償が高くなります。これに効くのが DenyLoginOnOverloadedServer、LoginQueueEnabled による参加の待ち行列、そしてサーバーパスワードです。
いますぐ IP アドレスを変えれば効果がありますか?
短い間だけで、Project Zomboid では追加の代償もあります。攻撃側はたいてい数分から数時間で新しいアドレスを見つけ直します。アドレスはサーバーリストの項目に載り、ステータス表示付きの Discord ボットが公開し、古い DNS レコードが残っていることもあるからです。さらにこのゲーム固有の事情があります。クライアントは探索済みのマップを、IP アドレスとポートから成るフォルダーにローカル保存します。変更後は、各プレイヤーがそのデータをサーバーから読み直します。
UFW や iptables で DDoS 攻撃に対抗できますか?
小規模な攻撃や作りの粗いボットには対抗できますが、ボリューム型攻撃には対抗できません。サーバー上のファイアウォールルールが判断するのは、すでにお使いの回線を通り終えたパケットです。回線が飽和していれば、プレイヤーのパケットはその手前で通れなくなり、ルールセットの出来とは無関係です。それでも有効なのは、16261 と 16262 に対する送信元アドレスごとのレート上限と、カーネルの接続追跡の負荷を下げることです。ボリューム型攻撃は、サーバーの手前のネットワークで終わらせる必要があります。
どのくらいの規模から、サーバーは自力で耐えられなくなりますか?
一般的なゲームサーバーは 1 Gbit/s につながっており、これは毎秒 125 メガバイトに相当します。ゲームサーバーのコミュニティに対する攻撃は、通常 5 から 50 Gbit/s です。同じくらい重要なのがパケットレートです。1 Gbit/s には 64 バイトのパケットなら毎秒約 149 万パケットが入りますが、通常のサーバーのカーネルが処理できるのはそのうち数十万にすぎません。つまり帯域幅を使い切っていない攻撃でも、お使いのサーバーを止められます。
KernelHost のサーバーは、攻撃を受けている間オフラインになりますか?
いいえ。ヌルルーティングは使いません。お使いの IP アドレスはネットワークに残り、破棄されるのは有害なパケットだけです。標準で含まれる基本保護は、フランクフルトにおける 3.2 Tbps の Arbor リアルタイムフィルタリングです。Advanced DDoS Protection を利用すると、グローバルなスクラビングネットワークにおける最大 17 Tbps の緩和能力が加わります。常時動いており、攻撃を受けてから反応する必要はありません。つまり、最初の数分だけプレイヤーが外に取り残される、ということが起きません。
KernelHost の DDoS 対策は別料金ですか。また、Advanced DDoS Protection が必要になるのはどんなときですか?
3.2 Tbps の基本保護はすべてのサーバープランに追加料金なしで含まれ、提供開始時点から有効なので、注文も有効化も必要ありません。Advanced DDoS Protection が必要になるのは、プロジェクトがたまたまではなく狙って何週間も攻撃され、フィルタリングをご自身で制御したい場合です。専用の保護 IP を受け取り、保護ルールをポートとプロトコルごとにカスタマーエリアで自分で管理できます。変更はリアルタイムで反映されます。料金は月額 50.00 EUR、PrePaid、最低利用期間なし、初期費用なしです。

Project Zomboid Project Zomboid の DDoS 対策 ゲームサーバー保護 ポート 16261 ポート 16262 servertest.ini RCON Advanced DDoS Protection