ローカルLLMでインフラログを自動分析する仕組みを作った話 #
ファイアウォール、認証基盤、スイッチ、ロードバランサー、Webサーバーのログを15分ごとにAIが自動分析し、異常検知・重大度判定・対処提案をSlackに通知。ログデータは一切外部に送信しません。
なぜ作ったのか #
きっかけは単純で、ログを見る時間がないという問題でした。
BESTNET-CLOUDでは複数のファイアウォール、L2/L3スイッチ、Windows AD、ロードバランサー、Webサーバーが稼働しています。それぞれがsyslogを出しますが、日常的に全部のログを人間が目視で確認するのは現実的ではありません。Zabbixでリソース監視はしていますが、syslogの中身を読んで「この攻撃パターンは放置していいのか、対処すべきなのか」を判断する部分は人間の仕事のままでした。
AWS DevOps Agent(2026年3月GA)やAzure Security Copilotなど、パブリッククラウド側にもAIによるログ分析サービスは出てきています。しかし、これらはクラウド上のリソースが主な対象であり、オンプレミスの物理機器のsyslogを直接パースして分析する機能はありません。さらに、ログデータがクラウドベンダーのAI基盤に送信されるため、閉域要件のある環境では使えません。
であれば、自分で作るしかない。幸い、ローカルで動くLLMの性能は実用レベルに達しており、必要なコンポーネントはすべてオープンソースで揃います。
全体構成 #
システムの名前はBASTION(バスティオン)。城砦・最後の砦という意味で、閉域環境でインフラを守るという世界観を込めました。
構成はシンプルです。
使っているコンポーネントは以下の通りです。すべてオープンソースまたは無料枠で動いています。
| コンポーネント | 役割 | ライセンス |
|---|---|---|
| rsyslog | 全機器のsyslogを一元受信・ホスト別保存 | OSS(GPL) |
| シェルスクリプト群 | 機器別ログ要約・パース・前処理 | 自社開発 |
| OpenClaw | AIエージェント基盤(LLM連携・Slack連携・コマンド実行) | OSS |
| Qwen2.5-14B | ローカルLLM(日本語ログ分析・異常判定) | OSS(Apache 2.0) |
| GPUStack | GPU推論サーバー(OpenAI互換API提供) | OSS |
| Slack(Socket Mode) | 通知・双方向対話 | 無料枠 |
データフローの詳細 #
1. ログ収集(rsyslog) #
各機器からsyslogをUDP/TCP 514で受信し、ホスト名・年・月・プログラム名でディレクトリを分けて保存します。
/var/log/remote/ fw-primary/2026/04/filterlog.log ad-server/2026/04/Security-Auditing.log lb-server/2026/04/loadbalancer.log ...
2. ログ要約(summarize.sh) #
15分ごとにcronが summarize.sh を実行し、各機器のログから直近30分間のイベントを抽出して構造化されたテキストサマリーを生成します。
各機器のログは形式がまったく異なるため、パース処理は機器ごとに書き分けています。例えばファイアウォールのfilterlogはカンマ区切りで、送信元IPは19番目、宛先ポートは22番目のフィールドです。Windows ADのログはバイナリデータが混入するため grep -a が必須です。こうした機器固有の知識をスクリプトに落とし込む部分が、この仕組みのコア作業です。
3. AI分析(analyze.sh) #
要約テキストをOpenClaw経由でローカルLLM(Qwen2.5-14B)に投入します。プロンプトで「重大度を判定し、検知した異常と推奨対処をJSON形式で返せ」と指示しています。
ここで重要な設計判断が2つあります。
セッション分離:分析のたびにセッションIDを動的に生成し、過去の会話履歴がコンテキストに混入するのを防いでいます。LLMは前回の分析結果に引きずられて判断がブレることがあるため、毎回クリーンなコンテキストで分析させます。
誤検知制御:正常な動作パターン(NextcloudのLDAP定期認証、Kerberos自動認証、ファイアウォールの外部スキャンブロック等)をシステムプロンプトに定義し、ノイズとして除外する判定基準をLLMに与えています。運用しながらパターンを追加していく形です。
4. 通知(notify.sh) #
LLMの分析結果をSlackに送信します。重大度に応じて色分け(critical=赤、high=橙、medium=黄、low=緑)しています。
medium以上の場合は、自動的に2通目の詳細分析を追加送信します。この2通目には生ログの上位50行が添付されるため、オペレーターは通知を見ただけで「何が起きているか」と「生データ」の両方を確認できます。
5. 対話的分析(Slack双方向) #
定期分析とは別に、Slackで @OpenClaw-Monitor ファイアウォール分析 のようにメンションすると、指定した機器の詳細分析を即座に実行できます。「VPN認証に兆候はあるか」「同一IPが複数の攻撃手法を試行していないか調べて」といった自然言語での質問にも対応します。
OpenClawがbashコマンドを実行できるため、将来的にはFWルールの動的追加やサービスの隔離といった自動対処にも拡張可能です。
GPU要件 #
意外と少ないリソースで動きます。
| 項目 | 消費量 |
|---|---|
| モデル本体(Qwen2.5-14B Q4量子化) | 約9GB |
| KVキャッシュ(16Kトークン時) | 約1〜2GB |
| 合計 | 約10〜11GB |
対応している機器 #
| 機器種別 | 分析内容 |
|---|---|
| ファイアウォール | 攻撃ブロック数・攻撃元IP・ポート分布・VPNエラー |
| 認証基盤(AD) | ログイン成功/失敗/ロック・失敗元IP・失敗アカウント |
| ロードバランサー | バックエンド別5xxエラー率 |
| L2/L3スイッチ | リンクダウン・ループ・ストーム検知 |
| Webサーバー | HTTPステータス分布・敏感URL・4xx/5xx元IP |
syslog出力に対応する機器であれば、パーススクリプトを追加するだけで監視対象に含めることができます。FortiGate、Cisco、Palo Alto等も同じ方式で対応可能です。
運用してわかったこと #
LLMは「判断」に使い、「データ処理」はスクリプトでやる #
当初はLLMに生ログを直接渡して全部やらせようとしましたが、syslogのフィールド位置を間違えたり、カウント計算がずれたりします。LLMは数値の正確な集計が苦手です。現在はログのパース・集計・要約はシェルスクリプトが行い、LLMは要約テキストを読んで「異常か正常か」「どう対処すべきか」を判断する役割だけを担っています。
誤検知制御は運用しながら育てる #
最初の1週間は誤検知だらけでした。KerberosのコンピューターアカウントがADに定期認証するたびにログイン成功として1,000件以上レポートされ、NextcloudのLDAP連携が「不審なログイン試行」として検知されました。1つずつシステムプロンプトに正常パターンとして追記していくと、2週間ほどでノイズがほぼゼロになりました。
セッション分離は必須 #
セッション機能をそのまま使うと、前回の分析結果がコンテキストに残り、LLMが「前回の報告と比較して…」と余計な文脈を持ち込みます。セキュリティ分析では毎回フレッシュな目で見ることが重要なので、分析ごとにセッションIDを動的生成する方式にしました。
「何も起きていない」という報告にも価値がある #
LOWの通知が15分ごとに来ると、最初は「うるさいな」と感じます。しかし運用を続けると、この通知が「システムが正常に動いている」という安心材料になっていることに気づきます。通知が来なくなったときに「監視自体が止まっている」ことに気づけるのは、この定期通知のおかげです。
今後やること #
現在は「検知→通知」までですが、ここから先は「検知→AIが判断→自動対処」まで拡張する計画です。
具体的には、攻撃元IPの自動ブロック(FW APIを直接叩く)、ブルートフォース検知時の自動遮断、異常リソース検知時の自動スロットリングなどを実装していきます。また、ZabbixやAWS CloudWatch、Azure Monitorなど既存の監視基盤からのアラートをWebhook経由で受信し、BASTIONがLLMで横断分析→自動対処するハイブリッド構成も検討中です。
まとめ #
ローカルLLM(Qwen2.5-14B)+GPUStack+OpenClaw+rsyslog+シェルスクリプトという構成で、インフラログの自動分析を実現しました。V100 16GB 1枚で動き、ログデータは外部に出ず、月額のランニングコストはGPU電気代だけです。
すべてのコンポーネントがオープンソースなので、仕組みとしては誰でも再現可能です。ただし、機器ごとのログパース、誤検知パターンの蓄積、システムプロンプトのチューニングといった「動かしきる」部分にはそれなりの工数と運用ノウハウが必要です。
BASTIONは現在、ベストネット合同会社の自社インフラ(BESTNET-CLOUD)で24時間本番稼働しています。