WebサーバーにAIアクティブファイアウォールを実装した話

WebサーバーにAIアクティブファイアウォールを実装した話

2 min read

2026.04 / Tech Blog / BASTION

WebサーバーにAIアクティブファイアウォールを実装した話 #

Fail2Banの固定閾値では検知できない未知のBotパターンやスパムリクエストを、ローカルLLMが15分ごとに分析して自動ブロックする仕組みを実装した。既存のnginx + Fail2Banの上にAI分析層を追加し、防御を3層構造にした。

Fail2Banは優秀だが「未知」に弱い #

WebサーバーのBot対策として、nginxのUA map + レートリミット + Fail2Banの組み合わせは定番です。403を10回/分出したIPを1時間Banする。シンプルで確実。

しかしこの方式には構造的な弱点があります。

Fail2Banの閾値は「固定」。「403が10回/分」のような静的条件でしかトリガーされない。UAを変えながらゆっくりクロールするBot、403ではなく200を返すパスを連打するスパム、正規のブラウザUAを偽装した高頻度アクセスは、Fail2Banの閾値をすり抜ける。人間がアクセスログを目視で見れば「明らかにおかしい」と分かるパターンでも、固定ルールでは捉えられない。

BASTIONではこの「人間なら気づくが固定ルールでは捉えられないパターン」をローカルLLMに判断させます。

防御の3層構造 #

既存のnginx + Fail2Banの上にBASTIONのAI分析層を追加し、3層構造にしました。

担当判断方式対応速度
第1層nginx(UA map / レートリミット / deny.conf)静的ルール即時(リクエスト単位)
第2層Fail2Ban(firewalld連動)固定閾値(403が10回/分)1分以内
第3層BASTION(LLM分析 → SSH経由firewalld)LLMがログの文脈を判断15分以内

各層は独立して動作します。Fail2Banが先にBanしたIPはBASTIONが重複チェックして二重ブロックを防止。BASTIONの強みは「未知のパターンを検知できる」点です。

監視項目 #

BASTIONのWebサーバー監視テンプレートは、以下の6カテゴリを15分ごとに分析します。

カテゴリデータ源検知内容
HTTPステータス分布アクセスログ403/429/5xx集中IP。正常時との偏差
Bot UA検知アクセスログ未知のBot UA × 高頻度リクエスト
スパムリクエストアクセスログ言語切替連打等の特定パラメータ連打
マルウェア検知ClamAVログアップロードファイルのウイルス検出
SSH認証失敗sshdログFailed password / Invalid user
アプリケーションエラーPHP-FPMログFATAL/ERRORレベル

ブロックの仕組み #

なぜWAN境界のFWではなくWebサーバー側でブロックするのか #

BASTIONのリアクティブ防御は、通常はWAN境界のファイアウォールAPI(OPNsense等)で攻撃元IPをブロックします(前回の記事参照)。しかし、WebサーバーがDNATで公開されている構成では、WAN境界FWのブロックリストではWebサーバー宛のトラフィックを捕捉できない場合があります。

そこで、Webサーバー側のfirewalld + nginx deny.confに直接ブロックルールを入れる独立した防御経路を用意しました。

BASTION (分析サーバー)
  → SSH接続(専用ユーザー・公開鍵認証・最小権限sudo)
  → firewall-cmd でIPをdrop(L3/L4レベル)
  → nginx deny.conf にIP追記 + reload(L7レベル)

SSH接続のセキュリティ #

分析サーバーからWebサーバーへのSSH接続は、専用のサービスアカウントを使い、sudo権限は必要最小限のコマンドだけ許可しています。

# sudoersの許可コマンド(これ以外は実行できない)
svc-monitor ALL=(root) NOPASSWD: /usr/bin/firewall-cmd
svc-monitor ALL=(root) NOPASSWD: /usr/sbin/nginx
svc-monitor ALL=(root) NOPASSWD: /usr/bin/tee -a /etc/nginx/deny.d/*
svc-monitor ALL=(root) NOPASSWD: /usr/bin/sed -i * /etc/nginx/deny.d/*

rootログインではなく、専用のサービスアカウントを作成し、ISMS審査にも耐えうる最小権限設計です。

Fail2Banとの違い #

 Fail2BanBASTION
判断方式固定閾値(「403がN回/分」)LLMがログの文脈を読んで判断
未知パターン検知不可(ルール追加が必要)ログの異常パターンを自動検知
UA偽装403が出ないと検知不可リクエスト頻度×パス×時間帯で判断
ClamAV連携なしFOUND検知→アップロード元IP追跡→ブロック
通知メール(MTA依存)Slack(即時通知、対話操作可能)
解除bantimeで固定24時間自動解除 + Slackから即時解除可能
監査fail2ban.log構造化監査ログ([HB_BLOCK]/[HB_UNBLOCK]タグ)

Fail2Banを置き換えるのではなく、共存させます。Fail2Banは「403連発」を1分以内に検知してBanする。BASTIONは「403には至らないが明らかに不自然なパターン」を15分ごとのLLM分析で検知する。担当領域が異なるので、両方動かすことで死角が減ります。

実際の動作 #

分析レポート #

15分ごとの定期分析で、Webサーバーのセクションが自動的に出力されます。

incoming-webhook 07:15

Webサーバー詳細分析

リクエスト: 1,847件
ステータス: 200=1,650 / 403=112 / 429=45 / 5xx=0
403集中IP: xxx.xxx.156.12 (40件) — UA: GPTBot/1.0
Bot疑いUA: “SomeNewBot/2.0” (180件/15分) — 未登録UA
ClamAV: 検知なし
SSH失敗: 0件 / PHP-FPM ERROR: 0件

自動ブロック実行 #

incoming-webhook 00:53

🛡️ Webサーバーブロック実行

IP: xx.xxx.156.12
理由: bot_spam
firewalld: drop 追加済み
nginx deny: 適用済み

手動解除: @OpenClaw-Monitor ブロック解除 xx.xxx.156.12

ClamAV FOUND検知時の自動対処 #

ClamAVがアップロードファイルからマルウェアを検出した場合、BASTIONは即座にCRITICAL判定を出します。ClamAV自体はファイルを隔離するだけですが、BASTIONはさらにアクセスログからアップロード元IPを特定し、firewalldで自動ブロックします。ファイルの隔離(ClamAV)+ ネットワークの遮断(BASTION)の二段構えです。

nginx deny.confは「best-effort」設計 #

firewalldブロックとnginx deny.confの二重防御を設計しましたが、nginx deny.confのディレクトリ設定がない環境でも、firewalld単独で防御が機能するように設計しています。deny.confが使えない場合は「skipped」とログに記録し、firewalldだけで続行。後からnginxのinclude設定を追加すれば、コード変更なしで自動的にnginx denyも有効化されます。環境の準備状況に合わせて段階的に強化できる設計です。

まとめ #

WebサーバーにBASTIONのAI分析層を追加し、nginx(第1層)→ Fail2Ban(第2層)→ BASTION(第3層)の3層防御を構築しました。固定閾値では捉えられない未知のBotパターンやスパムリクエストを、ローカルLLMが15分ごとに自動検知してfirewalldに即座にブロックを入れます。

SSH接続は専用アカウント・最小権限sudo・公開鍵認証。nginx deny.confはbest-effort設計で、環境の準備状況に応じて段階的に有効化可能。Fail2Banとは共存し、それぞれが異なる領域をカバーします。

BASTIONは閉域環境でAIセキュリティ監視を実現するサービスです。

BASTION サービスページ
お問い合わせ

Updated on 2026年4月24日

What are your feelings

  • Happy
  • Normal
  • Sad