メインコンテンツにスキップ

Elastic Security 統合

2か月以上前に更新

このガイドでは、外部インフラを使用せずに Push 配信(Webhook 2.0) を使って Axur Platform のフィードを Elastic Security に取り込む方法を説明します。
本手順では、Elastic Stack のネイティブ機能(インデックス、Ingest Pipeline、Watcher)だけを使用して、データをアイテム単位のドキュメントに分割します。

重要: これはあくまで一例の統合手法です。インデックス設計やデータ変換は、お使いの環境や要件に合わせてカスタマイズ可能です。以下の手順は、Axur フィードから直接データを取り込み、エンティティごとに特定のインデックス(例:チケットや認証情報)に分割することを目的として設計されています。

注記: このチュートリアルでは、すでに Axur Platform へのアクセス権と必要な API キーをお持ちであることを前提としています。


前提条件

  • Elastic Stack(Elasticsearch + Kibana) バージョン 8.x

  • Kibana への管理者アクセス権

  • Axur インフラから Elastic クラスターへの ネットワークアクセス

  • 対象インデックスへの書き込み権限を持つ Elastic API キー


コストおよび課金に関する考慮事項

  • 重要: この統合では Elastic の組み込み REST API と Watcher を使用します。Axur 側での課金は発生しません。

  • 主なコスト要因:

    • 使用する Elastic ライセンス/機能(Watcher は適切なライセンスが必要)

    • 取り込んだイベントおよび派生インデックスのストレージ

    • ホスティング環境に応じたネットワークの送受信量

  • コストを抑えるためのヒント:

    • 初期はより絞り込んだフィードフィルターを使用してデータ量を制限

    • ここで作成するインデックスに ILM(Index Lifecycle Management)ポリシー を適用

    • 取り込み状況を監視し、必要に応じてフィードフィルターを調整

ヒント:このチュートリアルで使用されている Elastic 用語の用語集は、ドキュメントの末尾に掲載されています。


1)Axur API キーを作成する

API キーを作成し、後の手順で使用できるよう値を控えておきます。

API キーの生成方法:

  1. Axur Platform で API Keys 設定に移動

  2. 新しい API キーを作成し、API キーの値を安全にコピー

注記:フィードは、API キーのユーザーがアクセス権を持つデータのみを返します。

スクリーンショット:

この時点(ステップ 2~6)以降のすべての設定は、Elastic/Kibana コンソール内で実施 します。


2)Elastic で:入力用インデックスを作成する

HTTP POST 経由で Axur データを直接受信するためのインデックスを作成します。
動的フィールドを扱うために、flattened マッピングを使用してください。

PUT axur-feed-input
{
"mappings": {
"dynamic": true,
"dynamic_templates": [
{
"collectionData_flattened": {
"path_match": "collectionData.*",
"mapping": { "type": "flattened" }
}
}
]
}
}

スクリーンショット:


3)Elastic で:Ingest Pipeline を作成する

入力インデックスに届いた各ドキュメントに、取り込みタイムスタンプ を追加するパイプラインを作成します。

PUT _ingest/pipeline/axur-feed-input-pipeline
{
"processors": [
{ "set": { "field": "ingested_at", "value": "{{_ingest.timestamp}}" } }
]
}

重要: Axur フィードの Push URL には、必ず ?pipeline=axur-feed-input-pipeline を付加して、このパイプラインを適用してください。

スクリーンショット:


4)Elastic で:出力用インデックスを作成する

これらのインデックスは、エンティティごとに分割されたアイテム単位のドキュメント を格納します。

チケット用インデックス:

PUT axur-feed-ticket_splitted
{
"mappings": {
"dynamic": true,
"properties": {
"item": { "type": "flattened" },
"feedData": { "type": "flattened" }
}
}
}

認証情報(detections)用インデックス:

PUT axur-feed-credential_splitted
{
"mappings": {
"dynamic": true,
"properties": {
"item": { "type": "flattened" },
"feedData": { "type": "flattened" }
}
}
}

スクリーンショット:


5)Elastic で:チェックポイント用インデックスを作成する

最後に処理したタイムスタンプを保存し、データの再処理を防ぐ ためのインデックスです。

PUT axur-feed-checkpoint
{
"mappings": {
"properties": {
"last_ts": { "type": "date" }
}
}
}

スクリーンショット:


6)Elastic で:アイテムを分割する Watcher を作成する

この Watcher は、新規の入力ドキュメントのみを処理 し、分割したアイテムを出力インデックスに格納するとともに、チェックポイントを更新します。

PUT _watcher/watch/axur_split_batch
{
"trigger": { "schedule": { "interval": "1m" } },
"input": {
"chain": {
"inputs": [
{
"cp": {
"search": {
"request": {
"indices": ["axur-feed-checkpoint"],
"body": {
"size": 1,
"query": { "ids": { "values": ["checkpoint"] } }
}
}
}
}
},
{
"src": {
"search": {
"request": {
"indices": ["axur-feed-input"],
"body": {
"size": 200,
"query": {
"range": {
"ingested_at": {
"gt": "{{#ctx.payload.cp.hits.hits}}{{ctx.payload.cp.hits.hits.0._source.last_ts}}{{/ctx.payload.cp.hits.hits}}{{^ctx.payload.cp.hits.hits}}1970-01-01T00:00:00Z{{/ctx.payload.cp.hits.hits}}"
}
}
},
"sort": [{ "ingested_at": "asc" }]
}
}
}
}
}
]
}
},
"condition": {
"script": {
"lang": "painless",
"source": "def h = ctx?.payload?.src?.hits; if (h == null) return false; def t = h.total; if (t == null) return false; if (t instanceof Map) return (t.value != null && t.value > 0); return (t > 0);"
}
},
"transform": {
"script": {
"lang": "painless",
"source": """
def tics = new ArrayList();
def creds = new ArrayList();
def maxTs = null;

for (def hit : ctx.payload.src.hits.hits) {
def src = hit._source;
if (src == null) continue;

def ts = src.containsKey('ingested_at') ? src.ingested_at : null;
if (ts != null) {
if (maxTs == null) { maxTs = ts; }
else if (java.time.ZonedDateTime.parse(ts).isAfter(java.time.ZonedDateTime.parse(maxTs))) { maxTs = ts; }
}

def feed = src.containsKey('feedData') ? src.feedData : null;
if (!src.containsKey('collectionData')) continue;
def cd = src.collectionData;

if (cd != null && cd.containsKey('tickets') && cd.tickets != null) {
for (def it : cd.tickets) {
if (it == null) continue;
tics.add(['feedData': feed, 'item': it]);
}
}
if (cd != null && cd.containsKey('detections') && cd.detections != null) {
for (def it2 : cd.detections) {
if (it2 == null) continue;
creds.add(['feedData': feed, 'item': it2]);
}
}
}

return ['tics': tics, 'creds': creds, 'next_checkpoint': maxTs];
"""
}
},
"actions": {
"index_tics": {
"foreach": "ctx.payload.tics",
"max_iterations": 500,
"transform": { "script": { "lang": "painless", "source": "return ctx.payload._value;" } },
"index": { "index": "axur-feed-ticket_splitted", "execution_time_field": "indexed_at", "refresh": "wait_for" }
},
"index_creds": {
"foreach": "ctx.payload.creds",
"max_iterations": 500,
"transform": { "script": { "lang": "painless", "source": "return ctx.payload._value;" } },
"index": { "index": "axur-feed-credential_splitted", "execution_time_field": "indexed_at", "refresh": "wait_for" }
},
"update_checkpoint": {
"condition": { "script": { "lang": "painless", "source": "return ctx.payload.next_checkpoint != null;" } },
"transform": { "script": { "lang": "painless", "source": "return ['last_ts': ctx.payload.next_checkpoint];" } },
"index": { "index": "axur-feed-checkpoint", "doc_id": "checkpoint", "execution_time_field": "updated_at", "refresh": "wait_for" }
}
}
}

スクリーンショット:


7)Axur PUSH フィードのエンドポイントを設定する

Axur フィードを Elastic の入力インデックス に向け、パイプラインを適用します。

  • エンドポイント URL: https://YOUR_ELASTIC_CLUSTER/axur-feed-input/_doc?pipeline=axur-feed-input-pipeline

  • 追加するヘッダー:

    • Authorization: ApiKey <YOUR_ENCODED_ELASTIC_API_KEY> (Elastic API Keys UI から取得した Encoded 形式 を使用)

  • Secret Key: フィード内で安全なシークレットを設定 Axur はリクエストを HMAC 署名 で送信 必要に応じて Elastic 側で検証可能

スクリーンショット:


検証

設定後、入力インデックスにテストドキュメントを送信 して動作を確認します。
(Kibana → Dev Tools を使用)

POST axur-feed-input/_doc?pipeline=axur-feed-input-pipeline
{
"feedData": { "feedType": "ticket", "customerKey": "TEST" },
"collectionData": {
"tickets": [ { "ticket": { "id": "TCK123", "type": "leak" } } ],
"detections": [ { "credential": { "user": "alice" } } ]
}
}

約 1 分待って、以下を確認します:

GET axur-feed-ticket_splitted/_search

GET axur-feed-credential_splitted/_search

GET axur-feed-checkpoint/_doc/checkpoint

各出力インデックスにアイテム単位のドキュメントが作成され、チェックポイントには last_ts が更新されていることを確認します。
その後の実行では、同じ入力ドキュメントが再処理されないことを確認してください。

スクリーンショット:


トラブルシューティング

  • 出力インデックスにドキュメントがない場合:

    • Watcher が有効でエラーが発生していないか確認

    • Watcher > History をチェック

  • 401 / 403 インデックスエラー:

    • Elastic API キーの権限(書き込み、インデックス作成)を確認

  • 重複が発生する場合:

    • チェックポイントドキュメントが更新されているか確認

    • クラスターの時刻同期を検証

  • データが全く取り込まれない場合:

    • Axur から Push URL への到達性を確認

    • パス内の pipeline パラメータが正しいか確認


完了:データの確認場所とアラート例

  • チケット: axur-feed-ticket_splitted インデックスに格納

  • 認証情報(detections): axur-feed-credential_splitted インデックスに格納

例:Kibana → Discover でのクエリ

GET axur-feed-ticket_splitted/_search
{
"query": { "term": { "item.detection.status": "open" } },
"size": 20,
"sort": [{ "indexed_at": { "order": "desc" } }]
}
GET axur-feed-credential_splitted/_search
{
"query": { "exists": { "field": "item.credential.user" } },
"size": 20,
"sort": [{ "indexed_at": { "order": "desc" } }]
}

検出ルールの作成 (Elastic Security → Rules → Create rule → Custom query)

  • インデックスパターン: axur-feed-credential_splitted

  • カスタムクエリ(KQL): item.credential.user:* and item.access.domain:"example.com"

  • スケジュール: 5 分ごと

  • 重大度(Severity): Medium

  • アクション: 通知を追加(メール、Slack など)


Elastic API キーの生成方法

Axur Push リクエストを認証するために、Elastic で API キーを作成します。

手順(Kibana 内):

  1. Stack Management → Security → API Keys → Create API key に移動

  2. 名前: axur-feed-ingest

  3. 権限:

    • Index privileges: axur-feed-*(または作成した特定のインデックス)に対して writecreate_index を付与

  4. 作成後、Encoded 形式 のキーをコピーして安全に保管

スクリーンショット:


用語集

  • Elasticsearch: Elastic Stack の分散型検索・分析エンジン

  • Kibana: Elasticsearch データの管理・可視化用 Web UI

  • Index: Elasticsearch 内のドキュメントの論理的な名前空間

  • Ingest Pipeline: ドキュメントをインデックス化する前に実行されるプロセッサ

  • Watcher: 定期的な分割などのアラート/自動化を実装する機能

  • ILM (Index Lifecycle Management): データ保持やパフォーマンスを管理するポリシー

  • API Key: Elasticsearch の認証メカニズム

  • Push (Webhook 2.0): Axur の配信モードで、イベントを直接指定したエンドポイントに送信


ご不明点があれば、いつでも [email protected] までお気軽にご連絡ください 😊

こちらの回答で解決しましたか?