Docker上のCrowdSecでHomeLabを保護する:協調型侵入防止の完全ガイド

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

アプローチの比較:静的ファイアウォール vs Fail2ban vs CrowdSec

NextcloudやVaultwarden、Plexなどのためにポート80や443を開放した瞬間から、自動化されたスキャンが始まります。わずか数分でボットは公開された管理画面、既知のCVE(脆弱性)、脆弱なSSHパスワードの探索を開始します。セルフホストサービスを保護する際、HomeLabの管理者は通常、次の3つの戦略から選択します。

  • 静的ファイアウォールルール(UFW、iptables、pfSense):エッジでポート番号単位や特定の国全体のIPレンジをブロックするのには適しています。しかし、静的ルールにはアプリケーションへの認識能力がまったくありません。ポート443を開放するファイアウォールルールでは、正当なユーザーがNextcloudを開いているのか、攻撃者がリバースプロキシ経由でディレクトリトラバーサルのペイロード(../../etc/passwd など)を送りつけているのかを判別できません。
  • Fail2ban:長年にわたりHomeLabの定番として使われてきたツールです。正規表現ルールでテキストログを監視し、ローカルのファイアウォールチェインを介して一時的なアクセス禁止(BAN)を追加します。単一のLinuxマシン上では確実に動作しますが、完全に隔離された状態で動作するという弱点があります。ボットネットのIPがあなたのサーバーに到達する前にインターネット上の10,000台のサーバーをスキャンしていても、自身のマシンが直接攻撃を受けるまでFail2banはそれを無視します。また、Docker環境でFail2banを設定する場合、ホストパスのログマウントやsystemdジャーナルの転送、壊れやすい正規表現パターンへの対応に苦労することになります。
  • CrowdSec(協調型侵入防止):Fail2banの核となるログ解析のアイデアに、分散型の脅威インテリジェンスを組み合わせた仕組みです。世界中のCrowdSecインスタンスのいずれかがIPから攻撃を受けると、そのシグナルが分析されます。合意(コンセンサス)が得られると、該当の攻撃元IPは共有のグローバルブロックリストに登録されます。また、CrowdSecは検知(Security Engine)と適用・遮断(Bouncer)を分離しているため、コンテナ化されたスタック上でも非常にクリーンに運用できます。

DockerでCrowdSecを実行するメリットとデメリット

他のコンテナと一緒にCrowdSec Security EngineをDocker内で実行すると、デプロイをシンプルに維持できますが、いくつかのトレードオフを念頭に置いておく必要があります。

メリット

  • 疎結合なアーキテクチャ:CrowdSecエンジンはユーザースペースで動作し、ログ解析のみを処理します。カーネルレベルの生ファイアウォール権限を必要としません。アクセスの遮断処理は、ホスト上やリバースプロキシ(TraefikプラグインやNginxモジュールなど)、さらにはルーター上で動作する軽量なバウンサーに委任されます。
  • プロアクティブなコミュニティ防御:他の場所で検知された攻撃の恩恵をサーバーが受けることができます。別の地域の悪質なスキャナーが何千ものWordPressサイトを標的にした場合、ボットがあなたのドメインに到達する前に、定期的なアップデートサイクルを通じてエンジンがそのBAN決定を取得します。
  • 分かりやすいYAMLルール:シナリオ、パーサー、修復プロファイルには可読性の高いYAMLファイルが使用されます。これにより、Gitでのバージョン管理が容易になり、Docker Composeを使って複数のノードに簡単にデプロイできます。
  • 最小限のリソース消費:Go言語で書かれたエンジンは高速で軽量です。1秒あたり50リクエスト未満を処理する一般的なHomeLabでは、コンテナのアイドル時のメモリ使用量は約60MBにとどまり、CPU使用率もほぼ無視できるレベルです。

デメリット

  • 複数のコンポーネントによる構成:単純な apt install fail2ban を実行するよりも導入の手間がかかります。Local API(LAPI)、ログ収集設定(acquis.yaml)、Hubコレクション、およびバウンサーが相互にどのように通信するかを理解する必要があります。
  • DockerのIPマスカレードに関する注意点:リバースプロキシやDockerブリッジネットワークが(X-Forwarded-For や X-Real-IP などのヘッダーを使用して)真のクライアントIPを転送しない場合、CrowdSecは内部ブリッジゲートウェイ(例:172.18.0.1)をクライアントとして認識してしまい、プロキシネットワーク自体をBANしてしまうリスクがあります。

HomeLab環境における推奨構成

単一ノードのHomeLabにおける、クリーンで実践的な構成例は以下のとおりです。

  1. CrowdSec Security Engine(Docker):コンテナとして動作し、Local API(LAPI)を 127.0.0.1:8080 で公開します。リバースプロキシ(Nginx Proxy Manager、Traefik、Caddyなど)のログディレクトリとホストの認証ログを読み取り専用(read-only)でマウントします。
  2. ホストファイアウォールバウンサー(ネイティブサービス):ホストOS上に直接インストールされ、iptables/nftablesを制御するsystemdサービスとして動作します。コンテナのLAPIに問い合わせを行い、トラフィックがDockerコンテナに到達する前にホストのカーネルレベルで悪意のあるパケットをドロップ(破棄)します。
  3. Hubコレクション:コンテナ内にインストールされる事前定義済みのルールパックです。SSHブルートフォース保護、Linux認証ログの解析、一般的なHTTPエクスプロイトへの対応、特定のリバースプロキシのアクセスログ解析などを処理します。

このように役割を分担することで、ログ解析をDocker内に閉じ込めつつ、実際のネットワークパケットの遮断は本来あるべき場所であるホストのネットワークレイヤーで直接確実に実行できます。

ステップバイステップ導入ガイド

ステップ1:ディレクトリ構造とDocker Composeの設定

CrowdSecの設定ファイルとSQLiteデータベースを保存するための専用ディレクトリをホスト上に作成します。

sudo mkdir -p /opt/crowdsec/config /opt/crowdsec/data
cd /opt/crowdsec

docker-compose.yml ファイルを作成します。

services:
  crowdsec:
    image: crowdsecurity/crowdsec:v1.6.3
    container_name: crowdsec
    restart: unless-stopped
    environment:
      - GID=1000
      - COLLECTIONS=crowdsecurity/linux crowdsecurity/sshd crowdsecurity/nginx crowdsecurity/http-cve
    volumes:
      - ./config:/etc/crowdsec
      - ./data:/var/lib/crowdsec/data
      - /var/log/auth.log:/var/log/auth.log:ro
      - /var/log/syslog:/var/log/syslog:ro
      - /var/log/nginx:/var/log/nginx:ro
    ports:
      - "127.0.0.1:8080:8080"
    security_opt:
      - no-new-privileges:true

ステップ2:ログ収集(Log Acquisition)の設定

CrowdSecが監視すべきログファイルと想定されるフォーマットを定義する必要があります。/opt/crowdsec/config/acquis.yaml を作成します。

filenames:
  - /var/log/auth.log
  - /var/log/syslog
labels:
  type: syslog
---
filenames:
  - /var/log/nginx/*.log
labels:
  type: nginx

コンテナをバックグラウンドで起動し、初期設定とデータベースを初期化します。

docker compose up -d

ステップ3:コレクションとパーサーの確認

コンテナ内でCrowdSecのコマンドラインツール(cscli)を使用して、パーサーとシナリオが正常に読み込まれていることを確認します。

# インストール済みのシナリオコレクションを確認
docker exec crowdsec cscli collections list

# アクティブなログパーサーを確認
docker exec crowdsec cscli parsers list

# リアルタイムの処理メトリクスを確認
docker exec crowdsec cscli metrics

ステップ4:ホストファイアウォールバウンサーのインストール

コンテナは脅威を検知しますが、ホスト上で悪意のあるトラフィックを遮断するための適用ツール(Bouncer)が必要です。まず、コンテナ内でバウンサー用のAPIキーを生成します。

docker exec crowdsec cscli bouncers add host-firewall-bouncer

ターミナルに出力された生成済みキーをコピーします。次に、公式リポジトリを追加し、ホストにファイアウォールバウンサーをインストールします(Debian/Ubuntuの例):

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt-get install -y crowdsec-firewall-bouncer-iptables

ホスト上の /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml を開き、LAPI接続を設定します。

api_url: http://127.0.0.1:8080/
api_key: YOUR_GENERATED_API_KEY_HERE
inactivity_threshold: 10s
ipset_type: nethash

バウンサーサービスを起動し、自動起動を有効化します。

sudo systemctl restart crowdsec-firewall-bouncer
sudo systemctl status crowdsec-firewall-bouncer

ステップ5:検知とルール適用のテスト

ローカル環境がグローバルネットワークと通信し、判定(Decisions)が正しく適用されているかを検証します。

# アクティブなローカルおよびコミュニティのBAN一覧を表示
docker exec crowdsec cscli decisions list

# ドキュメント用テストIP(RFC 5737)に対して10分間のBANを手動テスト
docker exec crowdsec cscli decisions add --ip 192.0.2.1 --type ban --duration 10m --reason "手動テストBAN"

# テストIPがホストのカーネルipsetテーブルに追加されたことを確認
sudo ipset list | grep 192.0.2.1

# テスト用のBANを解除
docker exec crowdsec cscli decisions delete --ip 192.0.2.1

この構成が稼働することで、HomeLabは受信トラフィックを能動的に監視し、コミュニティの脅威リストを自動的に取得して、セルフホストコンテナに到達する前にホストのファイアウォールで悪意のある通信を遮断できるようになります。

Share: