banner
r3n

r3n

Nothing Nowhere
twitter
discord user

Nohit.cc / DDoS対策の実践録

はじめに#

Minecraft サーバーは、常に DDoS 攻撃の脅威に晒されています。本記事では、2025 年 6 月末にサービスを終了した DDoS 保護サービス「Nohit.cc」の約 4 年間にわたる運営経験を元に、直面した課題とそれを乗り越えるために採用した技術的変遷を記録として共有します。

私自身、大規模 Minecraft サーバーの運営経験があり、その知見を活かす形で Nohit.cc を学生 3 人で立ち上げました。この記録が、同様の課題に直面するサーバー管理者や技術者の助けとなれば幸いです。

保護方式の変遷#

初期構成: HAProxy と手探りの無料サービス (2021 年)#

サービス開始当初は、Oracle Cloud の無料枠や私たちの余剰 VPS 上で HAProxy を稼働させる構成でした。docker kill -s HUPで既存接続を維持したまま設定をリロードできることを利用し、PHP 製の API で動的に設定を書き換えるという高校生お手製のおっかなびっくりシステムです。利用者はパネルから無作為なポートを割り当てられ、DNS には gdnsd を使いラウンドロビンで負荷分散していました。

しかし、利用者の急増により、このあり合わせのシステムでは安定稼働が困難となり、主要メンバー 1 名の離脱も重なったため、約半年で一時休止に至りました。

技術刷新:infrared への移行 (2021 年 8 月~)#

サービス再開にあたり、無料提供から「ユーザーで費用を分担し、より強固な保護を構築する」方針へ転換しました。システムも刷新し、プロキシソフトウェアを HAProxy から Go 言語ベースのinfrared(のフォーク)へと切り替えました。これにより、全ユーザーが 25565 ポートを利用し、ドメイン名で通信を振り分ける、より洗練された構成が実現しました。

Cloudflare Spectrum の導入と L7 攻撃との戦い (2022 年~2023 年初頭)#

infraredへの集約により多数のポートが不要になったため、Cloudflare Spectrum の利用を開始しました。強力な L4 の保護を(再販業者により)安価に導入できましたが、オリジンサーバーの IP が悪意のある利用者に露呈すると直接攻撃されてしまうという致命的な欠点を抱えていました。国内に安価で信頼性の高い上流 FW を持つ VPS がなかったため、一時的にこの構成を採用していました。

この時期から、攻撃の主流が単純な L4 フラッドから、より巧妙な L7 攻撃が増加する傾向にありました。特に、ログに残らないタイプの攻撃には苦戦を強いられました。

最終的に、不安定な挙動の原因は Cloudflare Spectrum 独自のレートリミットや仕様にあると判明。大量の新規接続を処理できず、プレイヤーの接続が不定期に切断される問題が発生していました。proxy-protocol を Spectrum <-> infrared 間にて利用する構成では L3/L4 単位のアクセス制御が難しく、アプリケーション側でのリアルタイム処理には限界がありました。

本格的な DDoS 保護への移行:GSL と Path.net の採用 (2023 年~2024 年)#

Spectrum の利用継続は非現実的と判断し、2023 年 2 月に GSL のカスタムファイアウォールを使用した環境へ移行。その後、CPU リソースを狙う新たな L7 攻撃に対応するため、一時的に Web Captcha 認証を導入するなどの対策も行いました。

2023 年 5 月には、コストパフォーマンスを評価し Path.net へ再度移行。これに伴い価格改定も実施しました。固定費のかかるベアメタルサーバーはスケールの柔軟性を欠くため、最終的には Linode, Datapacket 等を利用し、インフラのスケールを容易にしました。

2024 年に入ると、シンガポールや台湾・香港などアジア圏の需要に応える形で海外ロケーションを正式に追加。一方で、GeyserMC のアップデート追従の難しさや、競合サービスの台頭による需要の変化を踏まえ、2024 年 3 月に UDP のサポートを停止し、規模を最適化していきました。

最終的な保護構成の詳細 (2023 年以降)#

      +--------------+                +---------------+
      |   プレイヤー  |                | Vercel (Panel)|
      +--------------+                +---------------+
             |                              |
 (1. DNSクエリ) |                              | (A. パネル操作)
             v                              v
      +--------------+                +---------------+
      |    gdnsd     |                |      API      |
      +--------------+                +---------------+
             |                              |
 (2. IPを返す) |                              | (B. 設定反映)
             |                              |
             |                              v
             |                    +------------------+
             |                    |  infrared(fork)  |
             |                    +------------------+
             |                          ^      |
             +--------------------------+      | (C. Metrics)
               (3. 取得したIPに接続)           v
                                        +----------+
                                        | Grafana  |
                                        +----------+

全体構造#

最終的な構成は、管理者フローとプレイヤーの通信フローが、中央の infrared プロキシに集約される形です。ユーザー数の変動やコストの増減を考慮し、柔軟にスケールアップ / ダウンが可能な状態に落ち着かせました。

DNS / ロードバランシング#

海外 PoP を含む複数拠点を効率的に運用するには、GeoDNS(位置情報に基づく接続先変更)、Failover(障害時の自動切り替え)、RoundRobin(負荷分散)を組み合わせた高度な DNS 制御が不可欠でした。AWS Route53 / Constellix などの商用サービスはコストがかさむため、自前で構築できる gdnsd を採用しました。

特に、GeoDNS を利用したトラフィック分散は、単一拠点への負荷集中を回避する上で重要な役割を果たしました。
ユーザーのサーバーへの接続をドメイン名経由のみに限定し、各 PoP の IP アドレスへの直接接続は全て拒否する構成としていました。
これにより、L7 ボットネットが DNS 等を意図的に迂回しない限り、攻撃トラフィックもプレイヤーと同様にグローバルなインフラ全体へ分散されます。このアーキテクチャは、特定の拠点に攻撃が集中することを防ぐ上で、絶大な効果を発揮しました。

以下に、日本のユーザーに対する実際の設定例の一部を示します。

# データセンターと重み付けを定義
jpgeo => {
    map => map_japan
    up_thresh = 0.00000001
    service_types => mc
    plugin => weighted
    dcmap => {
        DC-JP => {
            JP01 => [1.1.1.1,1], #nht-tyo-1
            JP02 => [1.1.1.2,1], #nht-tyo-2
            JP03 => [1.1.1.3,1], #nht-tyo-3
            JP04 => [1.1.1.4,1], #nht-tyo-4
        },
        DC-SG => [1.1.1.5,1] #nht-sgp-1
        DC-UK => [1.1.1.6,1] #nht-lon-1
        DC-CN => [1.1.1.7,1] #Softbank
    }
}
# GeoIPデータベースを元に、アクセス元大陸/国に応じて最適なデータセンターを割り当て
map_japan => {
    geoip2_db => GeoLite2.mmdb,
    datacenters => [DC-JP,DC-SG,DC-UK,DC-CN],
    map => {
        AF => [DC-UK],
        AN => [DC-JP],
        NA => [DC-JP],
        SA => [DC-JP],
        AS => {
            default => [DC-JP],
            SG => [DC-SG],
            MY => [DC-SG],
            ID => [DC-SG],
            CN => [DC-CN],
        }
        OC => [DC-JP],
        EU => [DC-UK],
    }
}

ヘルスチェック#

Failover の精度を高めるため、mcpingでヘルスチェックを行いました。単なる TCP ポートの疎通確認では、L7 攻撃下などでサーバーが正常に応答しない状態でも「Up」と誤判定されるためです。mcping により、実際に Minecraft として応答可能かを基準に、より正確な死活監視を実現しました。

service_types = {
    mc = {
        plugin = extmon
        cmd = ["/etc/gdnsd/mcping/mcping", "%%ITEM%%", "25565"]
        interval = 8
        timeout = 5
        up_thresh = 3
        ok_thresh = 3
        down_thresh = 2
    }
}

各保護サーバーでの対策#

各 PoP では必要に応じて nftables を使用していました。攻撃状況に応じて動的にレートリミットを適用しました。

Nohit.cc の運営から得られた教訓#

Nohit.cc を 4 年間運営して得られた最大の教訓は、既製品では届かない領域を、自らの手で補うことの重要性でした。

その象徴的な例が、Minecraft (Java) が TCP を採用している点です。TCP のステートフルな性質は、UDP フラッドのような単純な攻撃を無視できる一方で、巧妙に設計された攻撃に対しては、特有の脆弱性を生み出します。これらを理解し、的確に対処するには、汎用的な DDoS 保護サービスだけでは不十分でした。

技術的な挑戦だけでなく、運営者として得た経験も非常に貴重でした。需要も供給も限られるニッチな領域で、自分たちが開発したサービスがコミュニティに受け入れられ、実際に役立っている手応えは、何物にも代えがたい喜びでした。時には公安から情報提供依頼を受けるという、一個人が技術を追求しているだけでは決して経験できない出来事もあり、サービスを社会的なインフラとして提供することの責任と面白さを同時に痛感しました。

本記事で共有した 4 年間の記録が、これから DDoS 対策に取り組む方々の、何らかの一助となれば幸いです。

次回の記事では、今回触れた GSL や Path.net といった各ホスティングプロバイダにおける DDoS 保護の具体的な「癖」と、その効果的な選び方について、さらに深掘りしていく予定です。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。