これから5回に分けて、Elastic Securityを使ったセキュリティ監視の基礎を、手を動かしながら学んでいきます。第1回はデータの取り込みと、Discover・Securityの両方で見えるようにするまでの環境構築です。
今後の予定
本シリーズでは、以下の流れでステップアップしていきます。
- 第2回:KQLでログを読み、最初の検知ルールを作る
- 第3回:Timelineで攻撃の全体像を追う
- 第4回:EQL / ES|QLで攻撃を自動検出・集計する
- 第5回:ノイズを減らし、運用できるルールにする
本ブログでは、ローカル環境に構築した Elastic Stack v9.3 を使用して、実際に手を動かしながら検証・解説を行っています。
Elastic Stack はオープンソースとして利用可能であり、クラウド版(Elastic Cloud)も無料トライアルで試すことができます。
- Elastic Stack(ダウンロード)
https://www.elastic.co/jp/downloads/- Elastic Cloud(無料トライアル)
https://www.elastic.co/jp/cloud/cloud-trial-overview
この記事を読むと何ができるか
- サンプルデータ82件をElasticsearchに正しく取り込める
- Discoverでイベントを確認できる
- Elastic Securityの画面でも同じデータが見える状態になる
まず覚えておく5つの用語
このシリーズ全体で繰り返し登場します。最初に整理しておきます。

- イベント:1件のログです。「ログイン成功」「プロセス起動」「外部への通信」など、「何かが起きた記録」です。このガイドでは 82件のイベントを使います。
- ルール:イベントを条件で監視し、怪しいものを自動で見つけるための設定です。「ログイン失敗が起きたら知らせる」という定義がルールです。
- アラート:ルールの条件に一致した結果です。イベントは「原材料」、アラートは「調査が必要かもしれない、という通知」です。アラートが出たからといって、必ずしもインシデントではありません。
- Timeline:複数のイベントを時系列で並べながら、攻撃の流れを追う調査画面です。第3章で詳しく使います。
- Case:調査メモ、担当者のアサイン、証拠をひとまとめにする入れ物です。チームで調査内容を共有するために使います。
演習データについて
今回使うサンプルデータ security_sample_v2.ndjson の概要です。
| 項目 | 値 |
|---|---|
| 形式 | NDJSON(1行1イベント) |
| 件数 | 82件 |
| 時間範囲 | 2025-03-18 09:45:00 〜 10:30:00(UTC) |
| 取り込み先インデックス名 | training-security-logs |
このデータはElastic Securityの学習用に設計されたサンプルです。完全な本番用ECSデータではありませんが、Discover・検知ルール・Timelineの練習には十分使えます。
ECS(Elastic Common Schema)とは 異なるログソース間でフィールド名を統一するための共通ルールです。WindowsイベントログでもLinux syslogでも、「ログイン失敗」は
event.outcome: "failure"と書く、という約束事です。この共通化によって、複数製品のログを横断して検索・分析できるようになります。
Step 1:ファイルをアップロードする
KibanaのIntegrationメニューから「Upload file」を開きます。画面遷移はバージョン差が出ることがあるので、迷ったら Global Search で検索して開いてください。


またはKibanaのホーム画面から「Upload a file」を選んでもかまいません。

security_sample_v2.ndjson を画面にドラッグ&ドロップします。Kibanaがファイルを自動解析します(数秒かかります)。

インデックス名をlogs-training-securityに指定します。

Step 2:インデックス名を確認する
「Advanced options」を展開し、「Create data view」にチェックが入っていることを確認します。このチェックが入っていると、取り込みと同時にDiscover用のデータビューが自動で作成されます。
training-security-logs⚠️ このインデックス名は正確に入力してください 第2回以降の手順でこの名前を前提にしています。別の名前で取り込むと、後の手順がすべて動作しません。
Step 3:マッピングを設定する
「Mappings」欄に次のJSONを入力します。マッピングとは「このフィールドを日付として扱う」「これをIPアドレスとして扱う」という型の定義です。省略すると集計や範囲検索が正しく動かなくなります。
{
"properties": {
"@timestamp": { "type": "date" },
"agent.type": { "type": "keyword" },
"ecs.version": { "type": "keyword" },
"event.kind": { "type": "keyword" },
"event.type": { "type": "keyword" },
"event.category": { "type": "keyword" },
"event.action": { "type": "keyword" },
"event.outcome": { "type": "keyword" },
"source.ip": { "type": "ip" },
"destination.ip": { "type": "ip" },
"destination.port": { "type": "integer" },
"network.bytes": { "type": "long" },
"network.transport": { "type": "keyword" },
"network.protocol": { "type": "keyword" },
"user.name": { "type": "keyword" },
"host.name": { "type": "keyword" },
"process.name": { "type": "keyword" },
"process.pid": { "type": "integer" },
"process.command_line": { "type": "wildcard" },
"process.parent.name": { "type": "keyword" },
"dns.question.name": { "type": "keyword" },
"rule.name": { "type": "keyword" }
}
}
マッピングが重要な理由:
@timestampがdate型でないと、時間範囲で絞り込めないnetwork.bytesがlong型でないと、合計・最大値の集計ができないsource.ipがip型でないと、CIDRなどのIP範囲検索が使えない
設定を確認したら「Import」をクリックします。「Import complete」と表示されれば成功です。


Step 4:Security画面でもデータを見えるようにする
Data Viewを作っただけでは、SecurityアプリはこのインデックスをElastic Securityが使うインデックス一覧に含みません。securitySolution:defaultIndex という設定にインデックス名を追加する必要があります。
Stack Management → Advanced Settings → securitySolution:defaultIndex現在の値の末尾に training-security-logs を追加して「Save changes」をクリックし、ページをリロードします。


なぜこの設定が必要か Elastic Securityはデフォルトで
logs-*、metrics-*などの決まったパターンのインデックスしか見ません。training-security-logsはそのパターンに含まれないため、明示的に追加する必要があります。本番環境でも、カスタムインデックスを使う場合は同じ手順が必要になります。
⚠️ バージョンについての注意
securitySolution:defaultIndexの設定箇所はElasticのバージョンによって異なる場合があります。公式ドキュメントも合わせて確認してください。
Step 5:時間範囲の調整
このサンプルデータは 2025-03-18 のタイムスタンプを持っています。Kibanaのデフォルト表示は「直近15分」や「Today」なので、そのままではデータが空に見えることがあります。取り込み失敗ではなく、単に時間範囲が合っていないだけです。
| 方法 | 操作 |
|---|---|
| ざっくり確認したい | 画面右上の時間範囲ピッカーで「Last 2 years」を選択 |
| 正確に指定したい | 「Absolute」で開始 2025-03-18 09:45:00、終了 2025-03-18 10:30:00 を入力 |
UTC と日本時間(JST)のズレに注意 サンプルデータのタイムスタンプはUTCで記録されています。Kibanaの表示はブラウザのタイムゾーン(日本環境ではJST = UTC+9)で表示されるため、画面上では
18:45〜19:30のように見えます。このシリーズでは時刻をUTCで記述します。画面上の表示が9時間ずれていても異常ではありません。
取り込みの確認
取り込みが完了したら、次の3つで正しく入ったか確認します。
確認1:件数確認
Dev Tools(Console)で実行します。
GET training-security-logs/_count
期待値:82
確認2:時間範囲確認
POST _query
{
"query": """
FROM training-security-logs
| STATS
total = COUNT(*),
earliest = MIN(@timestamp),
latest = MAX(@timestamp)
"""
}
期待値:
total = 82earliest = 2025-03-18T09:45:00.000Zlatest = 2025-03-18T10:30:00.000Z
確認3:数値フィールドの型確認
POST _query
{
"query": """
FROM training-security-logs
| WHERE network.bytes IS NOT NULL
| STATS
max_bytes = MAX(network.bytes),
sum_bytes = SUM(network.bytes)
"""
}
期待値:max_bytes = 120000000(120MB)
この値が返ってくれば、network.bytes が数値型として正しく取り込まれています。文字列型で取り込まれていると、この集計はエラーになります。
確認4:データ種別確認
POST _query
{
"query": """
FROM training-security-logs
| STATS count = COUNT(*) BY agent.type
| SORT count DESC
"""
}期待値:
winlogbeat =53packetbeat = 29
よくあるつまずきポイント
取り込んだはずなのにDiscoverに何も表示されない場合は、次を順番に確認してください。
- 時間範囲が「Last 15 minutes」になっていないか:「Last 2 years」に変更する
- Data Viewが
training-security-logsになっているか:左上のドロップダウンで確認 - インデックス名にタイポがないか:
training-security-log(sなし)は別のインデックス
Discoverでは見えるのにSecurityでは見えない場合は、Step 4の securitySolution:defaultIndex の設定を再確認してください。
この章のまとめ
| やったこと | なぜ必要か |
|---|---|
インデックス名を training-security-logs に指定 | 後の章の全手順がこの名前を前提にしているため |
| マッピングに型を明示 | 時間検索・数値集計・IP検索を正しく動かすため |
securitySolution:defaultIndex に追加 | Security画面でこのデータを使えるようにするため |
| 時間範囲を調整 | 2025-03-18の過去データを画面に表示するため |
第1回チェックリスト
- [ ]
GET training-security-logs/_countが82を返す - [ ] Discoverで
training-security-logsデータビューを開き、イベントが見える - [ ] Security → Rules 画面を開いたときにエラーが出ていない
次回は: KQLでログの中身を読みながら、最初の検知ルールを正しい条件で作ります。event.outcome:"failure" だけでは何が起きるか、第2回で確認します。

