アプローチの比較:静的ファイアウォール 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における、クリーンで実践的な構成例は以下のとおりです。
- CrowdSec Security Engine(Docker):コンテナとして動作し、Local API(LAPI)を
127.0.0.1:8080で公開します。リバースプロキシ(Nginx Proxy Manager、Traefik、Caddyなど)のログディレクトリとホストの認証ログを読み取り専用(read-only)でマウントします。 - ホストファイアウォールバウンサー(ネイティブサービス):ホストOS上に直接インストールされ、iptables/nftablesを制御するsystemdサービスとして動作します。コンテナのLAPIに問い合わせを行い、トラフィックがDockerコンテナに到達する前にホストのカーネルレベルで悪意のあるパケットをドロップ(破棄)します。
- 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は受信トラフィックを能動的に監視し、コミュニティの脅威リストを自動的に取得して、セルフホストコンテナに到達する前にホストのファイアウォールで悪意のある通信を遮断できるようになります。

