本番環境でFail2banが限界を迎え始めた理由
約6か月前、APIゲートウェイおよびNginxリバースプロキシとして稼働する20台のUbuntu VPSクラスタの運用を引き継ぎました。当時、システムはFail2banを用いて不正スキャンを遮断していました。しかし、運用開始直後に問題が浮き彫りとなりました。ボットネットが数万規模のクリーンなIPをローテーションさせながら攻撃してきたのです。各IPはわずか1〜2回のリクエストを送信してすぐに姿を消すため、Fail2banは設定されたしきい値(maxretry)に達する前に検知を逃し、完全に無力化されていました。
さらに、Fail2banはサーバー単体でローカルに動作します。あるIPがサーバーAを攻撃してBANされたとしても、その2秒後には何事もなかったかのようにサーバーBをスキャンできてしまいます。加えて、Nginxのログが1日15GBに達すると、Fail2banのPython製正規表現ワーカーが常時35〜40%のCPUリソースを消費する状態に陥っていました。そこで、システム全体をCrowdSecへと刷新することを決断しました。それ以来、新しいサーバークラスタを構築する際は必ず最初に導入するセキュリティツールとなっています。
CrowdSecの仕組みは何が違うのか?
CrowdSecは、検知と遮断のプロセスを明確に分離した3つのコンポーネントで構成されています。
- CrowdSec Security Engine (Agent): Golangで記述されており、メモリ消費量は60MB未満に抑えられています。各種ログ(Nginx、SSH、Syslog、Dockerなど)をパースし、YAML形式で定義された攻撃検知シナリオと照合する役割を担います。
- Remediation Components (Bouncers): 実際の遮断処理を実行するコンポーネントです。Engineが攻撃を検知して遮断判定を下すと、Bouncerがそのルールを
nftablesやiptables、Nginx Luaへ適用したり、ユーザーへCAPTCHAを提示したりします。 - Community Threat Intelligence (CTI): CrowdSec最大の強みです。自社サーバーがWordPressの脆弱性を狙うスキャンIPを検知すると、そのシグナルは匿名化されて中央の分析エンジンへ送信されます。世界中の数千台のサーバーで同様の挙動が確認されると、そのIPはグローバルブロックリストへと即座に追加されます。これにより、攻撃者が最初のリクエストを送ってくる前に、自社サーバーで先回りして自動遮断することが可能になります。
UbuntuにおけるCrowdSecのインストールと設定実践
以下は、Ubuntu 22.04 / 24.04 LTSでの具体的な導入手順です。
ステップ 1: CrowdSec Security Engineのインストール
常に最新のアップデートを取得できるよう、CrowdSecの公式リポジトリを追加します。
# APTリポジトリ設定スクリプトのダウンロード
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
# CrowdSecエンジンのインストール
sudo apt install -y crowdsec
# サービス状態の確認
sudo systemctl status crowdsec
起動後、CrowdSecは/var/log/auth.logなどのシステムログを自動的に検出し、LinuxやSSH向けの基本パーサーを有効化します。
ステップ 2: IP遮断を実行するFirewall Bouncerのインストール
Engine単体ではログの分析のみを行い、トラフィックの遮断は行いません。ファイアウォール層で遮断を実行するためにBouncerをインストールします(iptablesおよびnftablesの両方に対応しています):
# Firewall Bouncerのインストール
sudo apt install -y crowdsec-firewall-bouncer-iptables
# Local API(LAPI)へのBouncer登録状況を確認
sudo cscli bouncers list
正常にインストールされていれば、以下のような情報が表示されます:
------------------------------------------------------------------------------------------------------------------------
NAME IP ADDRESS VALID LAST API PULL TYPE VERSION
------------------------------------------------------------------------------------------------------------------------
firewall_bouncer-1696238491 127.0.0.1 ✔ 2024-03-20T10:15:30Z crowdsec-firewall-bouncer v0.0.28
------------------------------------------------------------------------------------------------------------------------
ステップ 3: Nginx Webサーバーの保護設定
Webサーバーを保護する場合、SQLインジェクション(SQLi)、パストラバーサル、ボットスキャン、既知のCVE攻撃を検知できるよう、Nginx用コレクションを追加インストールします:
# CrowdSec HubからNginxコレクションをインストール
sudo cscli collections install crowdsecurity/nginx
# ログソース設定ファイルを開く
sudo nano /etc/crowdsec/acquis.yaml
CrowdSecがアクセスログのパスを正しく読み込んでいるか確認します:
filenames:
- /var/log/nginx/*.log
labels:
type: nginx
---
新しいルールを適用するためにEngineを再起動します:
sudo systemctl restart crowdsec
ステップ 4: 統合管理のためのCrowdSec Console連携
2台以上のサーバーを管理する場合、全体を俯瞰できるダッシュボードが不可欠です。無料のWeb UIであるCrowdSec Consoleを活用しましょう:
# app.crowdsec.netでアカウントを登録し、Enrollキーを取得して実行:
sudo cscli console enroll <YOUR_ENROLL_KEY>
# サービスを再読み込み
sudo systemctl restart crowdsec
ステップ 5: 動作検証と日常運用でよく使うコマンド
cscliコマンドを使用して、ブロックリストの確認や手動でのIP遮断などを実行できます:
# 直近の攻撃アラート一覧を確認
sudo cscli alerts list
# 現在有効な遮断決定(Decisions)一覧を確認
sudo cscli decisions list
# 不審なIPを手動で4時間遮断
sudo cscli decisions add --ip 198.51.100.42 --duration 4h --reason "manual block malicious bot"
# 誤検知したIP(開発者やクライアントなど)を即座にブロック解除
sudo cscli decisions delete --ip 198.51.100.42
# パース済みログ数やマッチしたルールのメトリクスを確認
sudo cscli metrics
まとめ
Fail2banからCrowdSecへの移行により、インフラセキュリティは受動的な防御から能動的な先回り防御へと進化します。攻撃者がパスワード試行を繰り返すのを待つことなく、世界中のコミュニティから集約された数百万件の悪性IPリストを即座に適用できます。CPU負荷は大幅に削減され、不要なアクセスログも激減しました。さらに、CLIとWeb Consoleによる一元管理によって、運用チームが調査やトラブルシューティングに費やす時間を毎週何時間も削減することが可能になります。

