InfraGuard

検知 + JA3 シーケンス ルールセット

検知アルゴリズム(Kitsune・srct・nginx・JA3)の解説と、決定的ヒューリスティックによる JA3 シーケンス分析で異常行動ルールセット(infr_sec_ruleset)を導出・蓄積するフラッグシップ画面。

概要 — 何をする画面か

Security ▸ Detections(/security/detections)は InfraGuard の検知フラッグシップ画面です。3 つを 1 画面にまとめています。

  1. 検知アルゴリズムの解説 — 各エンジンがどのような原理で脅威を捕らえるかを教育用ポップオーバーで説明(Kitsune ML · srct ヒューリスティック · nginx is_suspicious · JA3)。
  2. 検知後の物語 — 各検知エンジンが直近のウィンドウで捕らえた異常 IP · 不審な Web アクセス · run 履歴を実データで可視化。
  3. ★ JA3 シーケンス ルールセット — 単一送信元 IP の時系列 JA3 フィンガープリント列を決定的ヒューリスティックが読み取り、その「連続した異常行動」を専門用語のルールセット(infr_sec_ruleset)として列挙・保存します。

収集と自動ブロックはすでにバックエンドで動いています(旧 stats-design の UI はファイアウォール・ブラックリストの表だけでした)。この画面の目的は、その隠れたテレメトリを信頼できる物語として表に出すことです。

この画面は読み取り中心 + オンデマンド分析です。検知エンジン自体(kts_tx・srct_tx・eve_ingest)は対象ホスト上で pm2 により動作する Node コレクターであり、アプリはそれらが埋めたテーブルを読むだけです。アプリ自身がトラフィックをスニッフィングすることはありません。

LLM によるナレーション経路は 2026-09-04 に削除されました。 以前はシーケンスの要約を AI アダプターに送り、その自由記述の回答を保存していました。実測で確認された 3 つの問題が理由です — LLM の結論(「JA3 ローテーション」)は比率計算 3 行がすでに出していたものと同じなのに 1 回あたり約 9,100 トークンを消費し、自由記述をそのまま保存するため書き手の言語が固定され英語セッションが韓国語のカードを読むことになり、フォールバック経路でも provider/model にアダプターの値を刻んでいたため保存済み 13 行のうち 10 行が model=kimi-k2.6 と名乗りながら実際はテンプレート出力でした。現在はヒューリスティックのみが動作し、外部呼び出しもトークン費用もありません。provider/model は実際に動いたものだけを記録します。


いつ使うか


画面構成

KPI ストリップ

KPI 意味 出典
AI 異常 選択ウィンドウ内の Kitsune 異常検知件数 kitsune_detail_log count
AI ブロック そのうち is_blocked=1(しきい値 + veto を満たしたもの) kitsune_detail_log where is_blocked
不審な Web アクセス ウィンドウ内の nginx is_suspicious=1 リクエスト数 nginx_meta_ct count
ルールセット 現在有効(status=active)なルールセット数 infr_sec_ruleset

最初の 2 つの KPI が「AI」なのは、Kitsune が実際に機械学習のオートエンコーダだからです — このラベルは事実なのでそのまま残します。

検知アルゴリズム パネル(edu ポップオーバー)

各エンジンのカードから原理 · 何を見るか · tip を開く教育用ポップオーバー。文言は静的な security.det.edu.* lang パックが保持します。

pm2 配備ガイド

検知コレクター 5 種を対象ホストに pm2 cron として配備するコマンドとソースコードを提供します(§データソース · pm2 表)。

検知ログと run 履歴

JA3 オフェンダーとルールセット


使い方

1) 検知状況を確認する

上部の**ウィンドウ切替(1h / 6h / 24h)**で観測ウィンドウを変更します(既定 24h)。KPI と検知ログがそのウィンドウで再計算されます。画面は約 30 秒ごとにポーリングし、サービス側は 30 秒キャッシュします。

オフェンダー一覧だけは、ウィンドウ設定に関わらず常に直近 6 時間です。JA3 ローテーションは数時間かけて蓄積するため、短いウィンドウではパターンが現れません(自動ブロックの 360 分 JA3 ウィンドウと整合)。

2) JA3 シーケンス分析を実行する(★)

  1. オフェンダー一覧から IP を選ぶ(または Overview・Threats からのディープリンク)か、**[分析]**をクリックします。
  2. サーバーが suricata_tls_ct からその IP の TLS JA3 シーケンスを時系列で取得します(ウィンドウ = 運用ポリシー sec_ai_window_min、既定 60 分 · 最大 200 行)。
  3. シーケンス長が最小値(sec_ai_min_seq、既定 5)未満なら insufficient_sequence としてスキップされます。
  4. ヒューリスティックがシーケンスを findings に分類します(下の規則表)。
  5. 結果がルールセットとして保存され、一覧と Overview のファネルが即座に更新されます。

レスポンス例:

{
  "ok": true,
  "provider": "heuristic",
  "model": null,
  "saved": 1,
  "seq_len": 37,
  "findings": [
    { "key": "ja3_rotation",
      "params": { "conns": 37, "variety": 34 },
      "category": "tls_anomaly",
      "severity": "crit", "action": "block", "confidence": 91 }
  ]
}

分析は決定的かつ無料です — 同じシーケンスからは常に同じルールセットが得られ、外部サービスを呼ばず、ネットワークがなくても動作します。実行コストがないので、オフェンダーの数値が変わったら気軽に再分析してください。

ヒューリスティック規則

findings はシーケンス統計から組み立てます(rotation = ja3_variety / seq_len)。

条件 ルールセット 分類 深刻度 推奨 信頼度
variety ≥ 3 かつ rotation ≥ 0.5 JA3 ローテーション(自動化スキャナ / ボットネット) tls_anomaly rotation≥0.9 → crit、それ以外 warn block 50 + round(rotation×45)、最大 95
機密 URL を観測(.env・.git・wp-config…) 認証情報 / 設定ファイルの探索 credential_access crit block 88
variety = 1 かつ conns ≥ 10 かつ sni_variety ≥ 4 単一 JA3 による多標的スキャン scan warn observe 72
上記のいずれでもない TLS ベースライン活動 other info observe 40

機密 URL は正規表現 .env .git wp-config .aws /actuator phpunit /.. shell.php wp-login xmlrpc でマッチします(nginx is_suspicious + suricata_http コンテキスト)。

分類・深刻度・推奨は挿入前にカラムの enum で検証されます(recon · credential_access · exfil · bruteforce · c2 · tls_anomaly · scan · other / info · warn · crit / observe · block · isolate · report)。

ルールセットの文言と言語

finding は文ではなく識別子として保存されます。heuristicFindings() は {key, params} を返し、行は rule_key + params(マイグレーション 000783)を保持します。文言は行を読む時点で、読み手の言語で適用されます。

000783 より前に作られた行は元のテキストを保持します。マイグレーションは、その行自身の evidence から旧テンプレートを再構成して完全一致した場合にのみ rule_key を復元します(推測はしません)。旧 LLM 経路が書いた自由記述の行は、その IP を再分析して置き換えられるまでそのまま残ります。

3) ルールセットを管理する

アクション 効果
有効化 status=active(Overview のファネル / ブロックの物語に反映)
保留 status=dismissed
削除 行を削除

再分析はその IP の既存の機械由来ルールセットのみを置き換えます(entity_type=ip, entity_key=ip, source=ai を削除して再作成) — 手作業で書いたルールセットは保持されます。

ルールセットの action フィールドは推奨であって命令ではありません。これに従って動作するコードはありません — 自動ブロックは suricata_tls_ct から JA3 ローテーションを直接計算し、infr_sec_ruleset を読みません。action=block のルールセットがあっても何もブロックされません。ブロックは Blocklist から行うか、自動ブロックのスケジューラが実行します。

4) スケジュールによる蓄積(オプトイン)

infr:sec-analyze コマンドが上位 JA3 オフェンダーを巡回してルールセットを蓄積します。単発実行して終了するコマンドなので、スケジュールに安全に登録できます(デーモンではありません)。

# ゲートを無視して 1 回実行(デバッグ)
php artisan infr:sec-analyze --force

# 単一 IP を分析(ゲート無関係)
php artisan infr:sec-analyze --ip=203.0.113.10

5) pm2 配備コマンドをコピーする

pm2 カードは**[コマンドをコピー](pm2 実行行)、[ソースをコピー](スニペット本体)、[インスタンス値を埋めてコピー]**(HOSTNAME/IP トークン置換)を提供します。ソースはシードされた Inventory ▸ Tools のスニペット(infr_snippet)から取得します。


データソース

読み取るレガシーテーブル(変更禁止)

テーブル 用途 供給コレクター
kitsune_detail_log 異常 IP・anomaly_score・is_blocked kts_tx
kitsune_process_log Kitsune の run 履歴 kts_tx
srct_process_log srct の run 履歴 srct_tx
nginx_meta_ct 不審な Web リクエスト(is_suspicious) nginx_shipper/aggregator
suricata_tls_ct JA3 シーケンス(ja3_hash・sni・version) eve_ingest
suricata_http_ct 分析用の HTTP コンテキスト eve_ingest
blacklist_info 自動ブロック結果(参照) kts_tx · srct_tx
ip_info_loop geo/ASN エンリッチメント —

アプリ所有の新規テーブル

pm2 配備コレクター

key 供給先 配備コマンド(cron-restart)
eve_ingest suricata_*_ct pm2 start infr_eve_ingest.cjs --name infr-eve --cron-restart="0 0 * * 6"
kts_tx kitsune_*_log · blacklist_info pm2 start infr_kts_tx.cjs --name infr-kitsune --cron-restart="0 0 * * 2"
srct_tx srct_process_log · blacklist_info pm2 start infr_srct_tx.cjs --name infr-srct --cron-restart="0 0 * * 4"
sync_black ipset · iptables pm2 start infr_sync_black.mjs --name infr-syncblack --cron-restart="*/5 * * * *"
sync_firewall firewall_status pm2 start infr_sync_firewall.cjs --name infr-firewall --cron-restart="0 0 * * 0"

サービスとルート

メソッド ルート
GET /security/detections(index)
GET /security/detections/live(ポーリング)
POST /security/detections/analyze(分析)
POST /security/detections/ruleset/save
POST /security/detections/ruleset/delete

アクセス権限

操作 ゲート
画面の閲覧 Security ロール領域へのアクセス(min_req 2) — demo(1)はセキュリティ領域自体が見えず、staff(5)・admin(10)は閲覧可能
分析 / ルールセットの保存・削除 user_level ≥ 2(canWrite)+ infr_audit_log 監査

トラブルシューティング & FAQ

分析が insufficient_sequence でスキップされる — その IP の suricata_tls_ct シーケンスが sec_ai_min_seq(既定 5)未満です。ウィンドウ(sec_ai_window_min、既定 60 分)を広げるか、オフェンダー一覧(6 時間ウィンドウ)からより活発な IP を選んでください。


関連

탐지 · AI JA3 시퀀스 분석
탐지 · AI JA3 시퀀스 분석