AIが攻撃を検知→Slackで承認→ファイアウォールに自動ブロックを入れる仕組みを作った #
BASTIONの「検知→通知」ループに「自動対処」を追加。ポートスキャンを検知したAIがブロック提案をSlackに投稿し、人間が承認するとOPNsenseのファイアウォールに即座にブロックルールが入る。24時間後に自動解除。
「検知して通知する」だけでは足りない #
これまでのBASTIONは、ログを分析して異常を検知し、Slackに通知する仕組みでした(第1回参照)。しかし通知を受けた後のアクション——攻撃元IPのファイアウォールブロック——は人間が手動でOPNsenseの管理画面を開いて操作する必要がありました。
深夜3時に通知が来て、翌朝ログインしてブロックする。その間6時間、攻撃者はスキャンし放題です。
そこでBASTIONにリアクティブ防御を実装しました。AIが攻撃を検知すると、ファイアウォールへのブロック追加を自動的に提案し、Slackで承認するだけでOPNsenseに即座にルールが入ります。
全体のフロー #
| ステップ | 実行者 | 動作 |
|---|---|---|
| 1. 攻撃検知 | analyze.sh(15分ごと) | ログ分析でポートスキャン・ブルートフォースを検出。severity: HIGH判定 |
| 2. ブロック提案 | propose-block.sh | ホワイトリスト照合→重複チェック→Slackに提案投稿 |
| 3. 人間承認 | オペレーター | Slackで @OpenClaw-Monitor 承認 block-XXXXX |
| 4. ブロック実行 | fw-action.sh | OPNsense APIでAlias(BASTION_AutoBlock)にIP追加 |
| 5. 自動解除 | auto-expire.sh(毎時cron) | 24時間経過後にAliasからIP削除 |
実際の動作 #
1. ブロック提案がSlackに届く #
15分ごとの定期分析でseverity: HIGHが検出されると、攻撃元IPのブロック提案が自動的にSlackに投稿されます。
ブロック提案 [block-20260423-003]
攻撃元IP: xxx.xxx.119.51
検出理由: port_scan — 3,003回のブロック/失敗
重大度: HIGH
自動解除: 24時間後
承認: @OpenClaw-Monitor 承認 block-20260423-003
却下: @OpenClaw-Monitor 却下 block-20260423-003
※ 30分以内に応答がない場合、自動的に却下されます。
ブロック提案 [block-20260423-004]
攻撃元IP: xxx.xxx.47.173
検出理由: port_scan — 977回のブロック/失敗
重大度: HIGH
自動解除: 24時間後
ブロック提案 [block-20260423-005]
攻撃元IP: xxx.xxx.102.23
検出理由: port_scan — 965回のブロック/失敗
重大度: HIGH
自動解除: 24時間後
1回の分析で最大3件まで提案されます。ブロック回数の多い順に上位IPが選ばれます。
2. 承認するとファイアウォールに即座に反映 #
Slackで承認コマンドを送ると、fw-action.shがOPNsenseのAPIを叩いてブロックリストにIPを追加します。
ブロック実行完了 [block-20260423-003]
IP: xxx.xxx.119.51
自動解除: 2026-04-24T13:37:14+09:00
OPNsense側では、BASTION_AutoBlockというAliasにIPが追加されます。このAliasを参照するWANブロックルールが事前に設定されているため、APIでAliasにIPを追加するだけで即座にブロックが有効になります。
3. 24時間後に自動解除 #
auto-expire.shが毎時cronで実行され、期限切れのブロックを自動解除します。
自動解除: xxx.xxx.119.51(24時間経過)
解除後に同じIPが再度スキャンを行えば、次の分析で再び提案されます。
安全機構 #
AIにファイアウォールを操作させる以上、誤判断で正常な通信を遮断しないための安全機構が必要です。5層の防御を入れました。
| 層 | 内容 | 目的 |
|---|---|---|
| ホワイトリスト | 内部IP・DNS・自社グローバルIPは絶対にブロックしない | 自分自身の通信を遮断するのを防止 |
| Slack承認ゲート | 人間が確認してから実行(初期フェーズ) | AIの誤判断を人間がキャッチ |
| レートリミット | 1時間あたり最大10件まで | 異常な大量ブロックを防止 |
| 自動解除 | 24時間で自動的にブロック解除 | 誤ブロックでも24時間で自動復旧 |
| 緊急フラッシュ | Slackから全ブロック即時解除可能 | 業務影響時の緊急ロールバック |
ホワイトリスト照合の実装 #
ホワイトリスト照合はPythonのipaddressモジュールで実装しています。CIDR表記(10.0.0.0/8等)に対応し、プライベートIP・ループバック・リンクローカル・マルチキャスト・予約済みアドレスは組み込みチェックで自動除外します。
# ホワイトリスト照合の流れ 1. 組み込みチェック: is_private / is_loopback / is_link_local / is_multicast / is_reserved 2. ファイル照合: block-whitelist.txt の各行(IP単体 or CIDR)に対して判定 3. 結果: exit 0=ブロック禁止 / exit 1=ブロック可
OPNsense APIとの連携 #
ブロックの実体はOPNsenseのAlias(IPアドレスのグループ)です。事前に「BASTION_AutoBlock」というAliasを作り、このAliasをSourceとするWANブロックルールを設定しておきます。
# IP追加(ブロック実行)
curl -k -u "${API_KEY}:${API_SECRET}" \
-X POST "${OPNSENSE}/api/firewall/alias_util/add/BASTION_AutoBlock" \
-d '{"address":"攻撃元IP"}'
# IP削除(ブロック解除)
curl -k -u "${API_KEY}:${API_SECRET}" \
-X POST "${OPNSENSE}/api/firewall/alias_util/delete/BASTION_AutoBlock" \
-d '{"address":"攻撃元IP"}'alias_utilはランタイムテーブルを直接操作するため、APIコール1つで即座にブロックが有効になります。ファイアウォールルールの再読み込みは不要です。
監査ログ #
すべてのブロック・解除・承認・却下・タイムアウトは監査ログに記録されます。
2026-04-23 13:31:33 [PROPOSE] new block-20260423-003 ip=xxx.xxx.119.51 reason=port_scan count=3003 2026-04-23 13:37:14 [BLOCK] approved block-20260423-003 ip=xxx.xxx.119.51 expires=2026-04-24T13:37:14 2026-04-24 00:00:03 [EXPIRE] auto-expire block-20260423-003 ip=xxx.xxx.119.51 api=done
grepでタグ([PROPOSE] / [BLOCK] / [EXPIRE]等)を指定すれば、特定操作だけ抽出できます。
段階的な自律化 #
現在はSlack承認ゲート方式ですが、実績を蓄積して段階的に自律化する設計です。
| フェーズ | モデル | 移行条件 |
|---|---|---|
| Phase 1(現在) | Slack承認ゲート | — |
| Phase 2 | 条件付き自律 | confidence: high かつ ブロック一定回以上 → 自動実行。それ以外は承認ゲート |
| Phase 3 | 完全自律 | 誤判定率が0.1%未満を3ヶ月維持 |
なぜ段階的にやるのか #
BASTIONの開発過程で、LLMが「存在しないインシデントを捏造する」ハルシネーションを実際に経験しています。あるアカウントが「18回ロックアウトされた」とレポートに記載されていましたが、実ログのイベントは0件でした。もしリアクティブ防御が先に実装されていたら、架空の攻撃IPをブロックしていた可能性があります。この経験が「まず人間が確認してから実行」という設計判断の根拠です。
Slack承認ゲートの限界も見えている #
OpenClawを経由したSlack承認では、複数コマンドの一括処理時にLLMが一部のコマンドを実行せず「完了した」と応答するケースが発生しました。エージェント基盤のLLMを挟む以上、この種の不確実性は構造的に残ります。フルオート化(analyze.sh→propose-block.sh→fw-action.shの直接パイプライン)では、LLMの応答生成を経由しないため、この問題は消えます。
まとめ #
BASTIONのリアクティブ防御は、ログ分析→ブロック提案→Slack承認→OPNsense APIブロック→24時間自動解除のフローを全自動で実行します。安全機構5層(ホワイトリスト、承認ゲート、レートリミット、自動解除、緊急フラッシュ)により、誤判断による業務影響を最小化しています。
現在はSlack承認ゲート方式で運用中ですが、実績データを蓄積し、段階的に自律化していく設計です。「検知→通知」で終わっていた監視システムが、「検知→判断→対処→自動解除」のループを閉じました。
BASTIONは閉域環境でAIセキュリティ監視を実現するサービスです。