Call of Duty サーバーを DDoS 攻撃から守る

公開日 読了時間 46 分

Call of Duty サーバーが本当に必要とするポートはどれか、なぜゲーム、クエリ、RCON が同じポートに載っているのか、getstatus リフレクションと RCON への攻撃をどう絞るか、そしてどの攻撃規模から手前のネットワークでのフィルタリングしか効かなくなるかを解説します。

Call of Duty サーバーを DDoS 攻撃から守る作業は、クラシックなタイトルでは対象がはっきりしています。相手になるのはちょうど 1 つの UDP ポート、server.cfg にある数個の Dvar、そしてエンジンが 2003 年から抱えている増幅の経路です。一方で、夜のラウンドの最中に全プレイヤーが同時に落ちてしまうサーバーは、ハードウェアに問題があることはまずありません。多くの場合は攻撃が走っていて、しかもサーバーが埋まっている時間帯を選んでです。

本記事ではまず、どのタイトルが対象になるかを示し、次に追加費用なしでご自身で固められる範囲を示し、続いてその対策が技術的にどこで限界を迎えるかを示し、最後にサーバーの手前のネットワークで何が起きる必要があるかを説明します。コマンドは Debian 12、Debian 13、Ubuntu 22.04 LTS、Ubuntu 24.04 LTS 向けに書かれており、root を前提としているため、一般ユーザーの場合は先頭に sudo を付けてください。

攻撃がいま進行中の場合:いまは server.cfg を変更せず、サーバーも再起動しないでください。まずは測定値を保存します(「ログを取る」の節を参照)。攻撃が終わってからでは、もう残っていません。

どの Call of Duty タイトルでサーバーを DDoS から守れるか

Call of Duty サーバーを DDoS から守れるのは、独自の専用サーバーを立てられるタイトルだけです。該当するのは Call of Duty(2003)、Call of Duty United Offensive、Call of Duty 2、Call of Duty 4 Modern Warfare、Call of Duty World at War のオリジナル版、そしてコミュニティのプラットフォームである Plutonium(World at War、Black Ops、Black Ops II、Modern Warfare 3)、IW4x(Modern Warfare 2)、CoD4X(Call of Duty 4)です。これらのタイトルはいずれも同じ構造を持っています。server.cfg が 1 つ、開いた UDP ポートが 1 つ、そして公開されたサーバーリストへの登録です。

新しい作品には、本記事は明確に当てはまりません。Warzone、Modern Warfare(2019)、Black Ops Cold War、Vanguard、Modern Warfare II、Modern Warfare III、Black Ops 6 には、借りられる専用サーバーがありません。対戦は Activision のマッチメイキング基盤の上で動くため、server.cfg もサーバーブラウザーも、ご自身で開放したり固めたりできるポートも存在しません。Activision がこれらのタイトル向けに公開しているポートの一覧(TCP の 3074 と 27014 から 27050、UDP の 3074、3478、27000 から 27031 など)は、クライアントとプラットフォームのポートを説明したもので、サーバーのポートではありません。Warzone で接続が切れる場合は、ご自身の回線の問題か Activision 側の問題であり、サーバーを借りて解決するものではありません。

なぜ Call of Duty サーバーが狙われるのか

Call of Duty サーバーには、都合のよい標的にしてしまう性質が 4 つ重なっています。第一に、掲載されたサーバーは自分の住所を自分で公開します。サーバーリストの登録情報には IP アドレスとポートが平文で載っており、そうでなければ誰も入れません。第二に、通信はすべて UDP で流れ、UDP には要求できるような接続確立の手順がなく、送信元アドレスは偽装できます。第三に、エンジンは誰からのステータス問い合わせにも応答し、そのためにゲームを起動する必要すらありません。第四に、リモート操作の RCON がゲーム本体と同じポートに載っています。

そこに社会的な要素が加わります。BAN されたプレイヤー、クラン同士の競合、何年も顔を合わせてきたコミュニティ内のもめ事です。攻撃を仕掛ける側には技術も、まとまった金額も必要ありません。いわゆる booter や stresser は月に数ユーロの定期購入として売られており、ゲームサーバーを経由する増幅攻撃はそこでの定番の商品です。DDoS 攻撃が具体的に何であるかは、記事 DDoS 攻撃とは何か で解説しています。

実際に問題になるポート

クラシックな Call of Duty サーバーが占有する UDP ポートはちょうど 1 つ、28960 です。この 1 つのポートで 3 つのことが同時に動きます。ゲームトラフィック、サーバーリストからのステータス問い合わせ、そしてリモート操作の RCON です。独立したクエリポートや独立した RCON ポートはありません。専用サーバーの起動行はどのタイトルでも同じ形で、違うのは実行ファイルの名前だけです。

+set dedicated 2 +set net_ip 0.0.0.0 +set net_port 28960 +set sv_maxclients 32 +exec server.cfg +map_rotate
タイトルまたはプラットフォーム 用途 ポート プロトコル
Call of Duty、United Offensive、Call of Duty 2、Call of Duty 4、World at War ゲーム、クエリ、RCON を共用 28960 UDP
同じマシンで動かす追加のインスタンス ゲーム、クエリ、RCON を共用 28961 から 28970 UDP
Plutonium T4(World at War) ゲーム、クエリ、RCON を共用 28960 UDP
Plutonium T5(Black Ops) ゲーム、クエリ、RCON を共用 28960 UDP
Plutonium T6(Black Ops II) ゲーム、クエリ、RCON を共用 4976 UDP
Plutonium IW5(Modern Warfare 3) ゲーム、クエリ、RCON を共用 27016 UDP
IW4x(Modern Warfare 2) ゲーム、クエリ、RCON を共用 28960 UDP
t7x(Black Ops III) ゲーム、クエリ、RCON を共用 27017 UDP
Call of Duty 4 のマスターサーバー(送信) サーバーリストと認可 20810 と 20800 UDP
Call of Duty 2 のマスターサーバー(送信) サーバーリストと認可 20710 と 20700 UDP
Call of Duty 1 のマスターサーバー(送信) サーバーリストと認可 20510 と 20500 UDP
IW4MAdmin 管理用のウェブ画面 1624 TCP
SSH サーバーへのアクセス 22 TCP

マスターサーバーのポートは、ファイアウォールの開放に入れるものではありません。20810 と 20800 は相手側の宛先ポートであり、お使いのマシンで待ち受けるポートではありません。お使いのサーバーが自分からサーバーリストに話しかけます。それでも多くのポート開放の手引きは、これらを受信方向で開けるよう勧めています。これは何の見返りもなく攻撃対象領域を広げるだけです。

Call of Duty で一般的な規模

自力で対処できる範囲かどうかを見極めたいときは、2 つ目の表のほうが重要です。満員のサーバーの平常時の負荷と、攻撃で問題になる数値を並べています。

項目 値
プレイヤー 1 人あたりの送信レート(sv_maxRate の一般的な値) 毎秒 2.5 万バイト
32 スロットが埋まったときの送信負荷 毎秒約 800 キロバイト、つまり約 6.4 Mbit/s
一般的なゲームサーバーの回線 1 Gbit/s、毎秒 125 メガバイトに相当
64 バイトのパケットにおける 1 Gbit/s のパケットレート 毎秒約 149 万パケット
回線上の getstatus 要求の大きさ 41 バイト(IP ヘッダー 20 バイト、UDP ヘッダー 8 バイト、ペイロード 13 バイト)
CISA の警告 TA14-017A による Quake ネットワークプロトコルの増幅率 63.9
そこから計算した getstatus 要求への応答 約 2600 バイト
CoD4X に組み込まれた getstatus の上限 20 秒あたり 20 件の応答
CoD4X に組み込まれた getinfo の上限 100 秒あたり 100 件の応答
KernelHost でゲームサーバー宛てに除去した UDP フラッド 112.2 Gbit/s 超
KernelHost でボイスサーバー宛てに除去した攻撃 毎秒 4150 万パケット超で 473.4 Gbit/s 超

ゲーム、クエリ、RCON が同じポートに載っている理由

これが Call of Duty で決定的な特徴です。クラシックな Call of Duty タイトルすべての土台になっている id Tech 3 エンジンには、ゲーム、問い合わせ、リモート操作を分ける別々のポートがありません。すべてが、1 つの UDP ポート上のいわゆるコネクションレスパケットで流れます。コネクションレスパケットとは、0xFF の 4 バイトで始まり、その後に命令名を平文で載せた UDP パケットのことです。getstatus、getinfo、getchallenge、connect、rcon がそれに当たります。

実際の帰結は面倒です。ゲームを一緒に止めずに、ファイアウォールで RCON だけをゲームから切り離すことはできません。ポート 28960 に対するルールは、常にすべてに当たります。クエリフラッドと RCON への攻撃を狙って選り分けたい場合は、ポート番号だけでなくパケットの中身を見る必要があります。まさにこのために、Call of Duty ではポートを基準にしたファイアウォールルールが、クエリポートの分かれているゲームより早く限界に達します。

Call of Duty の getstatus リフレクションとは何か

getstatus リフレクションとは、攻撃側が送信元アドレスを偽装した小さなステータス問い合わせを多数のゲームサーバーに送り、それよりはるかに大きな応答を本来の標的に届かせる増幅攻撃です。このときゲームサーバーは標的ではなく、増幅器です。この経路は id Tech 3 エンジンについて 10 年以上前から文書化されており、Quake 3 とその派生と同じように Call of Duty にも当てはまります。

影響は 2 つの方向から来ます。攻撃を受ける側としては、getstatus 要求の洪水が計算時間と送信帯域幅を食い、プレイヤーにはラグスパイクとして見えます。意図しない増幅器としては、見知らぬ被害者に応答を送り出し、不正利用の通報はご自身に届きます。どちらも同じポートで、同じパケットで起き、どちらも最初は使用率のグラフで無害に見えます。

getstatus パケットの姿

要求は 0xFF の 4 バイトと getstatus という語で構成され、合わせてペイロード 13 バイトです。IP ヘッダーと UDP ヘッダーを加えると、回線上では 41 バイトになります。Call of Duty のフォーラムで何年も回っているファイアウォールルールの長さ判定は、まさにここを狙っています。

iptables -A INPUT -p udp -m length --length 41:45 -m recent --set --name getstatus_cod
iptables -A INPUT -p udp -m string --algo bm --string "getstatus" -m recent --update --seconds 1 --hitcount 20 --name getstatus_cod -j DROP

応答は比べものにならないほど大きくなります。statusResponse はサーバー設定の全体を文字列として含み、さらに接続中のプレイヤーごとに 1 行を加えるため、満員のサーバーでは数キロバイトになります。CISA は UDP 増幅攻撃の一覧(TA14-017A)で Quake ネットワークプロトコルを増幅率 63.9 として挙げ、悪用される命令としてサーバー情報の交換を明示しています。これにより、偽装した要求 1 Mbit/s が被害者側では約 64 Mbit/s になります。比較すると、同じ一覧で DNS は 28 から 54、NTP は 556.9 です。

組み込みのクエリ抑制:sv_queryIgnoreTime と sv_queryIgnoreMegs

Call of Duty 4 には、サーバーバージョン 1.7 以降クエリ抑制が組み込まれています。ステータス問い合わせを送ってきたアドレスを記憶し、同じアドレスからのそれ以降の問い合わせを、設定できる時間だけ無視します。これを制御する Dvar は 4 つで、初期値は次のとおりです。

sv_queryIgnoreMegs        1
sv_queryIgnoreTime        2000
sv_queryBounceIgnoreTime  12000
sv_queryIgnoreDebug       0

sv_queryIgnoreMegs は、無視リストが使えるメモリー量を決めます。1 メガバイトで約 6.5 万アドレス、追加の 1 メガバイトごとに約 8.7 万アドレスが入ります。値 0 は抑制を完全に無効にしますが、設定が古い雛形から引き継がれているため、多くのサーバーでまさにこの状態になっています。sv_queryIgnoreTime は無視する時間で、単位はミリ秒です。sv_queryBounceIgnoreTime は、応答が「ICMP Port Unreachable」で戻ってきたとき、つまりお使いのサーバーが見知らぬ被害者に対する増幅器として悪用されている、まさにその場合に効きます。sv_queryIgnoreDebug 1 は一致をログに書き込むため、そもそも何か起きているのかを確認できます。

CoD4X を使っている場合は、サーバーコードに固定の上限も加わります。getstatus の応答は 20 秒あたり最大 20 件、getinfo の応答は 100 秒あたり最大 100 件、RCON のエラーメッセージは 100 ミリ秒あたり最大 1 件です。ソースコードのコメントは意図を明確に述べています。サーバーはあふれさせられてもかまわないが、そのときに送信帯域幅を浪費してはならない、というものです。優先順位の付け方としては正しいものですが、サーバーの手前でのフィルタリングを置き換えるものではありません。

Call of Duty の RCON が歴史的に問題である理由

RCON はサーバーのリモート操作の仕組みで、Call of Duty ではゲームポート上の暗号化されていない UDP パケットです。RCON の命令は回線上で次のような姿をしています。0xFF の 4 バイト、続いて rcon という語、続いて平文のパスワード、そして実際の命令です。暗号化もセッションもユーザーアカウントも 2 つ目の要素もありません。ここから、いずれも現実に起きる 3 つの問題が出てきます。

  • 盗み見。経路のどこかで通信を見られる人は、お使いの RCON パスワードを平文で読み取ります。これはご自身とサーバーの間にあるすべてのネットワークに当てはまり、パスワードを渡すすべての道具にも当てはまります。
  • 推測。ロックできるようなログインの仕組みはなく、10 回失敗したあとのアカウント停止もありません。攻撃側は好きな速度でパスワードを試し続けられます。オリジナルのサーバーはこれをまったく抑えず、CoD4X は 100 ミリ秒あたり 1 件のエラーメッセージに応答を抑えるだけで、試行を「Bad rcon」としてログに記録します。
  • リフレクション。RCON のエラーメッセージも、偽装されたパケットへの応答です。偽装した RCON パケットでお使いのサーバーを撃つ人は、それを小さな増幅器として使い、しかもサーバーは横でログを埋めていきます。

実務上の帰結はこうです。rcon_password は、RCON が本当に必要なときだけ設定してください。設定する場合は、長く、ランダムにします。CoD4X は最低 8 文字を求めますが、これは下限であって推奨ではありません。日常の管理は、開いたネットワーク越しの RCON ではなく、SSH とサーバーコンソールで行ってください。そして、自身が RCON で通信する IW4MAdmin のような管理用の道具を動かしている場合、そのウェブ画面のあるポート 1624 は開いたネットワークに置くものではありません。

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

この節が最も長いのは意図的です。きちんと設定された Call of Duty サーバーは、どこに置かれていようと、小規模から中規模の攻撃を自力で耐えます。

1. 現状把握:サーバーで何が待ち受けているか

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

ss -lntup

注目するのはローカルアドレスの列です。0.0.0.0:28960 と [::]:28960 は「インターネット全体から到達できる」、127.0.0.1:3306 は「ローカルのみ」で、ファイアウォールルールは不要という意味です。ゲーム本体のほかに、IW4MAdmin、Fast Download 用のウェブサーバー、統計用のデータベース、そして忘れられた 2 つ目のゲームインスタンスが並んでいることがよくあります。攻撃側からの見え方は、外部からのポートスキャンで分かります。

nmap -Pn -sU -p 28960-28970,4976,27016 YOUR.SERVER.IP.ADDRESS
nmap -Pn -p- --min-rate 1000 YOUR.SERVER.IP.ADDRESS

2. ゲームが本当に必要とするものだけを開けたままにする

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

ufw allow 22/tcp comment 'SSH'
ufw allow 28960/udp comment 'Call of Duty'
ufw allow from 203.0.113.10 to any port 1624 proto tcp comment 'IW4MAdmin'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose

203.0.113.10 はご自身のアドレスに置き換えてください。Plutonium T6 では 28960/udp の代わりに 4976/udp が、Plutonium IW5 では 27016/udp が入ります。複数のインスタンスを動かす場合は、実際に使っている範囲だけを開放してください。つまり、28960 から 28970 までをまとめてではなく、たとえば 28960:28962/udp です。何も待ち受けていないポートは侵入口にはなりませんが、攻撃を受けている間はそれでもカーネルに仕事をさせます。復旧手段まで含む詳しい手順は 自分を締め出さずに UFW ファイアウォールを設定する にあります。

3. server.cfg でクエリ抑制を有効にする

この 4 行は Call of Duty 4 サーバーのすべての server.cfg に必要で、数メガバイトのメモリー以外に何のコストもかかりません。

set sv_queryIgnoreMegs "4"
set sv_queryIgnoreTime "2000"
set sv_queryBounceIgnoreTime "12000"
set sv_queryIgnoreDebug "0"

4 メガバイトで約 32.6 万アドレスが入り、本格的なフラッドにも足ります。sv_queryIgnoreTime を初期値の 2000 ミリ秒より上げるときは慎重にしてください。サーバーリストとあらゆるサーバーブラウザーは同じ仕組みでお使いのサーバーに問い合わせるため、無視する時間を高くしすぎるとリストから消えます。抑制がそもそも効いているかを知りたいときは sv_queryIgnoreDebug を一時的に 1 にし、ログでディスクを埋めないよう、そのあとは 0 に戻してください。

4. ファイアウォールでクエリフラッドを選り分ける

エンジン側の抑制が効くのは、パケットがゲームプロセスに届いたあとです。ファイアウォールルールはより早く判断し、コストも小さくなります。次の 2 行は、送信元アドレスごとに getstatus を制限します。

iptables -A INPUT -p udp --dport 28960 -m length --length 41:45 -m recent --set --name cod_query --rsource
iptables -A INPUT -p udp --dport 28960 -m string --algo bm --string "getstatus" -m recent --update --seconds 2 --hitcount 4 --name cod_query --rsource -j DROP

1 行目は、ステータス問い合わせに典型的な長さのパケットを送ってきた送信元アドレスを記憶します。2 行目は、同じアドレスが 2 秒以内に 4 件を超えて送った時点から、それ以降の getstatus 要求を破棄します。2 秒あたり 4 件は、どのサーバーブラウザーにも足ります。フォーラムには毎秒 20 件という、はるかに緩い変種も流れていますが、これはきちんとしたリフレクションの波よりも、作りの粗いボットに効くものです。

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. RCON を無効にするか、狭く運用する

最も安全な RCON への入口は、存在しない入口です。rcon_password を空にすると、あらゆる RCON パケットが拒否されます。

set rcon_password ""

その際、細かい点に注意してください。サーバーはそれでも応答します。つまりエラーメッセージを返すため、小さな増幅器のままです。それを排除したい、しかも RCON は固定の 1 つのアドレスからしか使わないという場合は、手前でパケットを破棄します。

iptables -A INPUT -p udp --dport 28960 ! -s 203.0.113.10 -m string --algo bm --string "rcon " -j DROP

このルールには、知っておくべき副作用があります。文字列 rcon は理屈のうえでは接続中のプレイヤーのチャットパケットにも現れることがあり、そのパケットも破棄されます。実務では我慢できる範囲です。この副作用が嫌なら、ルールは使わず、空のパスワードか非常に長いパスワードだけで運用してください。

6. 参加フラッドとスロット枯渇を防ぐ

参加フラッドが狙うのは回線ではなく、ゲームのロジックです。攻撃側は getchallenge パケットと connect パケットを短い間隔で送り続け、すべてのスロットが中途半端な接続で埋まるまで続けます。すると本物のプレイヤーには「Server is full」と出るのに、ゲーム内には誰もいません。これに対しては次の設定が効きます。

set sv_maxclients "32"
set sv_reconnectLimit "3"
set sv_floodProtect "1"
set sv_connectTimeout "30"
set sv_timeout "120"

sv_reconnectLimit は、同じプレイヤーが連続して再接続できる回数を制限します。sv_floodProtect は、サーバーがプレイヤーごとに処理するクライアント命令の数を制限し、1 つのクライアントが命令でサーバーを遅くすることを防ぎます。sv_connectTimeout と sv_timeout は、中途半端な接続および無言の接続がスロットを占め続ける時間を決めます。ここに古い雛形の大きな値を残しておくと、攻撃側にスロット枯渇を容易にします。

CoD4X では sv_authorizemode が加わります。値 1 は正規のコピーを持つプレイヤーだけを通し、0 は持たないプレイヤーだけを通し、-1 は両方を通します。1 にすると使い捨てのクライアントの大半を締め出せますが、オリジナルのコピーを持たない本物のプレイヤーも失います。最も強い手立ては g_password によるサーバーパスワードで、通常の参加経路を使うものすべてに効きます。そして、はっきりさせておくべきことが 1 つあります。パスワードが守るのはゲームのロジックで、お使いの回線ではありません。サーバーをあふれさせる攻撃側は、そもそも参加する気がありません。そのパケットは拒否されますが、それでも届いてはいます。そこが要点です。

7. サーバーリストの登録とご自身のアドレス

ここでは願望ではなく正直さが役に立ちます。お使いの IP アドレスは秘密にできません。一度接続したプレイヤーは皆それを知っていますし、リストの登録はいずれにせよポートまで含めて公開します。server.cfg でマスターサーバーを設定しないことで、登録をやめることはできます(Dvar の名前は sv_master1、sv_master2 などです)。ただし、それは新しいプレイヤーへの可視性をすべて失うことになり、最も手軽な攻撃側にしか効きません。

サーバーリストの現状について一言。Activision の元々のマスターサーバー(codmaster.activision.com の 20510、cod2master.activision.com の 20710、cod4master.activision.com の 20810)は、古いタイトルについてはもう何も応答しません。いま掲載されたい場合はコミュニティのサーバーリストを使います。CoD4X は独自のものを運用しており、そのために sv_authtoken のトークンを要求します。Plutonium は独自のサーバーリストを備えています。とはいえ本質は変わりません。アドレスはそこでも同じように平文で載ります。

それでも効く習慣が 2 つあります。生の IP アドレスをご自身でどこにも公開しないこと、つまり Discord のチャンネルにも、クランのページにも書かないことです。そして、いざというときに参照をすべて壊さずにアドレスを変えられるよう、プレイヤーにはホスト名で接続させることです。ここでの定番の落とし穴は、古いアドレスを指す忘れられた A レコードです。これがあると、どんな変更も無意味になります。

8. ウェブ画面、データベース、Fast Download を開いたネットワークから外す

ほとんどの Call of Duty サーバーでは、ゲーム本体のほかにもまだ動いているものがあります。ポート 1624 にウェブ画面を持つ IW4MAdmin、マップの Fast Download 用のウェブサーバー、ときには統計用のデータベースです。これらのサービスはどれもそれ自体が攻撃対象領域であり、どれも無制限に開いたネットワークに置くものではありません。

1624 はご自身のアドレスに限定するか、SSH ポートフォワーディング経由で画面に到達し、そのあとローカルで http://127.0.0.1:1624 を開いてください。

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

データベースは 127.0.0.1 にバインドしてください。開いたネットワークに置く理由は、どんな場合にもありません。そして Fast Download は、ゲームプロセスの中ではなく専用のウェブサーバーに置いてください。負荷のかかったウェブサーバーは、そうしないとゲームがシミュレーションに必要とする計算時間をちょうど奪います。

9. いざというときにデータがあるようログを取る

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

sar -n DEV 1 10
ip -s link show eth0
dmesg -T | tail -50
tcpdump -ni eth0 udp port 28960 -c 200 -q

Call of Duty にはもう 1 つ、決定的な問いに答える 5 つ目のコマンドがあります。この取得はコネクションレスパケットだけを、つまりちょうど getstatus、getinfo、getchallenge、connect、rcon を表示します。

tcpdump -ni eth0 'udp port 28960 and udp[8:4] = 0xffffffff' -c 200 -A

そこに次々に変わるアドレスから getstatus が何百も並んでいるなら、クエリフラッドです。rcon が並んでいるなら、誰かがパスワードを推測しようとしています。getchallenge と connect だけが並んでいるなら、参加フラッドです。tcpdump では必ず -c で件数を区切ってください。全負荷の状態での取得は、すでに過負荷のサーバーにさらに負荷をかけます。測定値の読み方は DDoS 攻撃を検知する にあります。

ここまでの対策が限界を迎える地点

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

一度計算してみてください。32 スロットが満員のサーバーが送信するのは約 6.4 Mbit/s で、ギガビット回線の 1 パーセントにも届きません。同じ回線は、誰かが毎秒 125 メガバイトを送った時点で埋まります。月に 10 ユーロで注文できる攻撃は、まさにそこを狙って作られています。その後ろにあるお使いの iptables ルールの出来は、もう関係ありません。プレイヤーのパケットは、その手前で通れなくなっているからです。

2 つ目の指標はパケットレートで、Call of Duty では定期的にこちらが帯域幅より先に限界に達します。64 バイトの小さなパケットなら、1 Gbit/s の回線には毎秒約 149 万パケットが入ります。通常のサーバーのカーネルが破棄を始める前に処理できるのは、CPU とネットワークカードによりますがそのうち数十万です。getstatus 要求は 41 バイトで、それよりさらに小さいのです。お使いの回線を 3 分の 1 も埋めない攻撃でも、計算時間のすべてが破棄に取られるため、サーバーは止まります。運用者にはこれが「使用率はまったく高くなかったのに、それでも全部落ちた」という形で見えます。

Call of Duty には、この計算をさらに厳しくする特徴が加わります。ゲーム、クエリ、RCON が同じポートに載っているため、いざというときに 28960 を閉じることができません。それはサーバーを止めるのと同じです。そしてエンジンがステータス問い合わせに要求の何倍もの大きさで応答するため、攻撃側は同じ効果を得るために、ほかのゲームより少ない自分の帯域幅で足ります。

実際に起きる規模の目安として、KernelHost のサーバーでは、ボイスサーバー宛ての毎秒 4150 万パケット超で 473.4 Gbit/s 超の攻撃や、ゲームサーバー宛ての 112.2 Gbit/s 超の UDP フラッドなどを除去しています。これに対するローカルの設定はありません。ボリューム型攻撃は、サーバーの手前のネットワークで終わらせる必要があります。

KernelHost が用意している対策

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

KernelHost の DDoS 対策は 2 段階で構成されており、有効化も注文も設定もなしに常時動いています。

  • 第 1 段階:グローバルなスクラビングネットワークにおける 17 Tbps の緩和能力。 ボリューム型攻撃は、データセンターに届く前に、発生源の近くで除去されます。
  • 第 2 段階:フランクフルトにおける 3.2 Tbps の Arbor リアルタイムフィルタリング。 サーバーの直前で、プロトコル固有のパターンを検知し、パケット単位で破棄します。

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

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

クランやコミュニティによっては、たまたまではなく、狙って何週間も攻撃されます。そのために Advanced DDoS Protection があり、月額 50.00 EUR から、PrePaid、最低利用期間なしで利用できます。違いは容量の大きさではなく、制御できることにあります。

  • 専用の保護 IP をフランクフルトの中核から割り当て、お使いのサーバーを当社のネットワーク内で切り替えます。ご自身の側で作り直す作業はありません。
  • ポートとプロトコルごとに自分で管理できる保護ルールをカスタマーエリアで設定できます。28960 UDP で何を許可するかをチケットを書かずに指定でき、複数のインスタンスがある場合はポートごとに分けて指定できます。
  • 変更はリアルタイムで反映されます。そのため、攻撃が進行している最中に調整できます。
  • ゲームに合わせた保護プロファイルを用意しており、改造したアプリケーションや独自のアプリケーションを任意の TCP または UDP ポートで動かす場合にも対応します。これは Plutonium と CoD4X で重要な点です。これらのポートは初期設定から外れることがあるからです。

Advanced DDoS Protection は、KernelHost に置かれているサーバー向けです。お使いの Call of Duty サーバーがいま別の場所で動いていて、そこで定期的にネットワークから外されているなら、KernelHost への移転が状況を変える道です。

2 つの段階の比較

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

ほとんどの Call of Duty サーバーでは、標準で含まれる常時保護と、きちんとした server.cfg を組み合わせれば十分です。Advanced DDoS Protection は、誰かが個人的な問題として攻撃してくる場合への答えです。

よくある失敗とその対処

「IP アドレスを変えたのに、2 時間後にまたオフラインになった」:攻撃側は新しいアドレスを、古いアドレスと同じ情報源から得ています。多くはサーバーリストの登録、ステータス表示付きの Discord ボット、あるいは古い DNS レコードです。アドレスの変更は時間稼ぎであって、解決ではありません。

「自分が被害者なのに、事業者から不正利用の通報が届く」:その場合、お使いのサーバーは標的ではなく増幅器です。誰かが偽装した getstatus 要求を送り、お使いのサーバーは律儀に見知らぬ被害者へ応答しています。まず sv_queryIgnoreMegs が 0 になっていないか確認し、4 つのクエリ Dvar と第 4 節のファイアウォールルールを設定してください。

「リストでは満員なのに、サーバーは空っぽ」:これは参加フラッドで、当たるのはゲームのロジックであり、回線ではありません。これには sv_reconnectLimit、sv_connectTimeout と sv_timeout の短い値、そして迷うならサーバーパスワードが効きます。

「攻撃の最中にサーバーがサーバーリストから消える」:それは結果であって、原因ではありません。サーバーリストは同じステータス問い合わせで、お使いのサーバーが生きているかを確認します。応答が通らない場合、あるいはご自身の抑制によって破棄された場合、サーバーはオフラインとみなされます。ファイアウォールを疑う前に、sv_queryIgnoreTime が高すぎないか確認してください。

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

「サーバーは動いているのに、全プレイヤーにラグスパイクが出る」:まず CPU 負荷ではなく、インターフェースのパケットレートを見てください。sar -n DEV 1 10 に異常がないのにそれでも引っかかるなら、原因はたいてい Mod、行きすぎた sv_maxRate、あるいは単にラウンドに Bot が多すぎることです。

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

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

まとめ

  • クラシックな Call of Duty サーバーが必要とする開いたポートはちょうど 1 つ、28960 UDP です。Plutonium T6 では 4976 UDP、Plutonium IW5 では 27016 UDP です。
  • Call of Duty ではゲーム、ステータス問い合わせ、RCON が同じポートに載っています。ポート単位のルールで RCON をゲームから切り離すことはできず、そのためにはパケットの中身を見るルールが必要です。
  • getstatus リフレクションは、このゲームに特徴的な増幅の経路です。要求は 41 バイト、CISA の警告 TA14-017A によると Quake ネットワークプロトコルの係数は 63.9 で、応答は約 2600 バイトになります。
  • クエリ抑制を有効にしてください。sv_queryIgnoreMegs 4、sv_queryIgnoreTime 2000、sv_queryBounceIgnoreTime 12000 です。多くのサーバーでは 0 のまま、つまり無効になっています。
  • rcon_password は、RCON が本当に必要なときだけ設定してください。パスワードは暗号化されずに UDP を流れ、アカウント停止がないため何度でも推測できます。
  • マスターサーバーのポート 20810 と 20800 は送信方向の宛先ポートであり、受信の開放に入れるものではありません。
  • おおよそ 1 Gbit/s、あるいは毎秒数十万パケットからは、お使いの設定ではなく、サーバーの手前のネットワークだけが決め手になります。

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

よくあるご質問

Call of Duty サーバーはどのポートを必要としますか?
クラシックな Call of Duty サーバーが必要とする開いたポートはちょうど 1 つ、28960 UDP です。この 1 つのポートでゲームトラフィック、ステータス問い合わせ、リモート操作の RCON が一緒に動き、独立したクエリポートや RCON ポートはありません。Plutonium のプラットフォームでは初期設定が異なります。World at War と Black Ops も 28960 UDP を使い、Black Ops II は 4976 UDP、Modern Warfare 3 は 27016 UDP を使います。マスターサーバーのポート 20810 と 20800 は送信方向の宛先ポートであり、受信方向で開ける必要はありません。
この記事は Warzone、Modern Warfare、Black Ops 6 にも当てはまりますか?
いいえ。Warzone、Modern Warfare(2019)、Black Ops Cold War、Vanguard、Modern Warfare II、Modern Warfare III、Black Ops 6 には、借りられる専用サーバーがありません。対戦は Activision のマッチメイキング基盤の上で動くため、server.cfg もサーバーブラウザーも、ご自身で開放したり固めたりできるポートも存在しません。独自のサーバー、つまり独自の DDoS 対策が可能なのはクラシックなタイトルだけです。Call of Duty、United Offensive、Call of Duty 2、Call of Duty 4、World at War、そしてコミュニティのプラットフォームである Plutonium、IW4x、CoD4X です。
Call of Duty の getstatus リフレクションとは何ですか?
getstatus リフレクションとは、送信元アドレスを偽装した小さなステータス問い合わせを多数のゲームサーバーに送り、その大きな応答を本来の標的に届かせる増幅攻撃です。getstatus 要求の大きさは 41 バイトで、応答にはサーバー設定の全体に加えて接続中のプレイヤーごとに 1 行が入ります。CISA は警告 TA14-017A で Quake ネットワークプロトコルを増幅率 63.9 として挙げており、これは要求 1 件あたり約 2600 バイトの応答に相当します。対象になるのは、クラシックな Call of Duty タイトルすべての土台である id Tech 3 エンジンです。
自分のサーバーが第三者への攻撃の増幅器として悪用されています。どうすればよいですか?
まず組み込みのクエリ抑制を有効にしてください。server.cfg で sv_queryIgnoreMegs を 4、sv_queryIgnoreTime を 2000、sv_queryBounceIgnoreTime を 12000 にします。sv_queryIgnoreMegs が 0 だと抑制は完全に無効で、多くのサーバーでまさにこの状態になっています。あわせて、送信元アドレスごとに getstatus を 2 秒間で数件に制限するファイアウォールルールを加えてください。sv_queryIgnoreDebug を 1 にすると抑制が効いているかがログで分かり、そのあとは値を 0 に戻します。
Call of Duty で rcon_password が危険なのはなぜですか?
Call of Duty の RCON が、ゲームポート上の暗号化されていない UDP パケットだからです。命令は 0xFF の 4 バイト、rcon という語、平文のパスワード、そして実際のコマンドで構成されます。暗号化もセッションもユーザーアカウントも、失敗後のロックもありません。経路のどこかで通信を見られる人はパスワードを読み取り、見られない人でも何度でも推測できます。rcon_password は RCON が本当に必要なときだけ設定し、それ以外は空のままにして SSH で管理してください。
Call of Duty サーバーがいまオフラインです。DDoS 攻撃かどうかは、どこで見分けられますか?
CPU 負荷ではなく、インターフェースのパケットレートを見てください。sar -n DEV 1 10 で毎秒のパケット数とバイト数が、ip -s link show eth0 で破棄パケットのカウンターが分かります。サーバー自体はほとんど働いていないのに受信パケットが平常時の値を大きく超えているなら、攻撃です。どの種類かは、tcpdump とフィルター udp port 28960 and udp[8:4] = 0xffffffff でコネクションレスパケットを取得すれば分かります。そこに getstatus が何度も並んでいるなら、クエリフラッドです。
iptables や UFW で DDoS 攻撃に対抗できますか?
小規模な攻撃や作りの粗いボットには対抗できますが、ボリューム型攻撃には対抗できません。サーバー上のファイアウォールルールが判断するのは、すでにお使いの回線を通り終えたパケットです。回線が飽和していれば、プレイヤーのパケットはその手前で通れなくなり、ルールセットの出来とは無関係です。Call of Duty ではさらに、ポート 28960 にゲーム本体も載っているため、いざというときに閉じることができません。ボリューム型攻撃は、サーバーの手前のネットワークで終わらせる必要があります。
KernelHost のサーバーは、攻撃を受けている間オフラインになりますか?
いいえ。ヌルルーティングは使いません。お使いの IP アドレスはネットワークに残り、破棄されるのは有害なパケットだけです。保護は 2 段階です。グローバルなスクラビングネットワークにおける 17 Tbps の緩和能力と、フランクフルトにおける 3.2 Tbps の Arbor リアルタイムフィルタリングです。常時動いており、攻撃を受けてから反応する必要はありません。つまり、最初の数分だけサーバーがサーバーリストから落ちる、ということが起きません。
DDoS 対策は別料金ですか。また、Advanced DDoS Protection が必要になるのはどんなときですか?
2 段階の常時保護はすべてのサーバープランに追加料金なしで含まれ、提供開始時点から有効なので、注文も有効化も必要ありません。Advanced DDoS Protection が必要になるのは、サーバーがたまたまではなく狙って何週間も攻撃され、フィルタリングをご自身で制御したい場合です。専用の保護 IP を受け取り、保護ルールをポートとプロトコルごとにカスタマーエリアで自分で管理できます。変更はリアルタイムで反映されます。料金は月額 50.00 EUR から、PrePaid、最低利用期間なし、初期費用なしです。

Call of Duty Call of Duty の DDoS 対策 ゲームサーバー保護 ポート 28960 Plutonium CoD4X getstatus リフレクション RCON Advanced DDoS Protection