【Elastic】続 Defender for Endpoint のログを取り込んでみた
はじめに
先日書いた「Defender for Endpoint のログを取り込んでみた」で
書ききれなかった Filebeat を使った方式 を今回はまとめてみました。
本投稿で説明する内容
Elastic Agent で取り込んだ場合と同様に、Filebeat azure eventhub input を使って
Defender for Endpoint のデバイスログを Elasticsearch に取り込みます。
前提
・Event Hubs 及び Azure Blob Storage は事前構築済みです。(上記ブログ記事参照)
・Defneder for Endpoint のログは Event Hubs に転送済みです。(上記ブログ記事参照)
・Elasticsearch と Kibana は Standard Edtition で事前構築済みです。
・Filebeat と Logstash は事前にインストール済みです。
【参考】
・Filebeat のインストール方法(公式ページ)
・Logstash のインストール方法(公式ページ)
利用環境
各ソフトウェアのバージョンは以下の通りです。
Product | version |
---|---|
Windows OS | Windows 11 Pro 22H2 |
macOS | Sonoma 14.4.1(23E224) |
Defender マルウェア対策クライアント | 101.24032.0006 |
Defender エンジン | 1.1.24030.4 |
Defender ウィルス対策 | 1.409.620.0 |
Defender スパイウェア対策 | 1.409.620.0 |
Amazon Linux | 2023.2.20231113.0 |
Elasticsearch | 8.11.2 |
Kibana | 8.11.2 |
Logstash | 8.11.2 |
Filebeat | 8.11.2 |
【構成図】
・Filebeat の Azure eventhub input で Event Hubs からログを取得します。
・Logstash で JSON 解析、フィールド名修正、時刻情報取得等の ETL 処理を実施します。
全体構成図
実施手順
以下、実施手順になります。
- Filebeat の設定
- Logstash の設定
- Filebeat と Logstsh の起動
- ログの確認
1. Filebeat の設定
Filebeat で以下の設定を実施します。
- Event Hubs からのログ取得
- Logstash へのログ転送
- メタデータフィールドの削除
Filebeat 設定ファイルの編集コマンドは下記になります。
$ sudo vi /etc/filebeat/filebeat.yml
1-1. Filebeat inputs の設定
Event hubs からログを取得するための設定をおこないます。
filebeat.yml
の filebeat.inputs 句に以下の設定値を設定します。
filebeat.inputs:
- type: azure-eventhub
eventhub: "defenderhub"
consumer_group: "$Default"
connection_string: "Endpoint=sb://********************************"
storage_account: "teststaccount99"
storage_account_key: "********************************************"
storage_account_container: "testcontainer01"
【設定内容】
項目名 | 設定値 | 説明 |
---|---|---|
type | azure-eventhub | Event Hubs からログを取得することを宣言します |
eventhub | "defenderhub" | 「イベントハブ名」を入力します |
consumer_group | "$Default" | 「コンシューマーグループ名」を入力します |
connection_string | "Endpoint=sb://*******" | 「接続文字列 - 主キー」を入力します |
storage_account | "teststaccount99" | 「ストレージアカウント名」を入力します |
storage_account_key | "<ストレージアカウントキー>" | ストレージアカウントの「アクセスキー」を入力します |
storage_account_container | "testcontainer01" | 「ストレージコンテナ名」を入力します |
【参考】
・Azure eventhub input(公式ページ)
1-2. Outputs の設定
Event Hubs から取得したログを Logstash へ転送するための設定をおこないます。
filebeat.yml
の output.logstash 句に以下の設定値を設定します。
output.logstash:
# The Logstash hosts
hosts: ["10.0.4.104:5044"]
【設定内容】
項目名 | 設定値 | 説明 |
---|---|---|
hosts | ["10.0.4.104:5044"] | Logstash ノードに TCP5044 ポートでログを転送します |
【参考】
・Configure the Logstash output(公式ページ)
【補足】
合わせて、Elasticsearch への転送設定を無効化しておきます。
filebeat.yml
の output.elasticsearch 句をコメントアウトします。
# output.elasticsearch:
# hosts: ["localhost:9200"]
1-3. Processors の設定
メタデータフィールドの削除のための設定をおこないます。
filebeat.yml
の processors 句に以下の設定値を設定します。
processors:
# - add_host_metadata:
# when.not.contains.tags: forwarded
# - add_cloud_metadata: ~
# - add_docker_metadata: ~
# - add_kubernetes_metadata: ~
- drop_fields:
fields: ["agent", "azure", "ecs", "host", "input"]
【設定内容】
項目名 | 設定値 | 説明 |
---|---|---|
add_host_metadata | コメントアウト | host に関するメタデータフィールドを無効化します |
add_cloud_metadata | コメントアウト | cloud に関するメタデータフィールドを無効化します |
add_docker_metadata | コメントアウト | docker に関するメタデータフィールドを無効化します(今回は無効化しなくてもメタデータは出力されません) |
add_kubernetes_metadata | コメントアウト | kubernetes に関するメタデータフィールドを無効化します (今回は無効化しなくてもメタデータは出力されません) |
drop_fields.fields | ["agent", "azure", "ecs", "host", "input"] | 上記設定のコメントでは削除できないメタデータフィールドを明示的に削除します |
filebeat.yml
を保存して閉じます。(:wq!
で vi エディタを閉じます)
【参考】
・how to remove filebeat metadata(Stack overflow)
・Drop fields from events(公式ページ)
2. Logstash の設定
Logstash で以下の設定を実施します。
- Filebeat からのログ取得
-
message
フィールドの JSON 解析 -
[properties][AdditionalFields]
フィールドの JSON 解析 - フィールド名の
properties
の削除 -
Timestamp
フィールドの時刻情報の取得 - 不要なフィールドの削除
- Elasticsearch へのログ転送
Logstash パイプラインファイルの編集コマンドは下記になります。
$ sudo vi /etc/logstash/conf.d/logstash.conf
2-1. input の設定
Filebeat からログを受信するための設定をおこないます。
logstash.conf
の input 句に以下の設定値を設定します。
input {
# input from Filebeat
beats {
port => 5044
}
}
【設定内容】
プラグイン名 | 項目名 | 設定値 | 説明 |
---|---|---|---|
beats | port | 5044 | Filebeat から TCP5044 ポートでログを受信します |
【参考】
・Beats input plugin(公式ページ)
2-2. filter の設定
取得したログを Elasticsearch に格納するために必要な加工処理をおこないます。
logstash.conf
の filter 句に以下の設定値を設定します。
filter {
# parse message field in json format
json {
source => "message"
}
# parse properties.AdditionalFields in json format
json {
source => "[properties][AdditionalFields]"
}
# rename fields starting with properties
ruby {
code => "
event.get('properties').each {|k, v|
event.set(k, v)
}
event.remove('properties')
"
}
# use Timestamp field for @timestamp
date {
match => ["Timestamp", "ISO8601"]
timezone => "UTC"
}
# delete redundant field
mutate {
remove_field => ["message", "[event][original]", "AdditionalFields"]
}
}
【設定内容】
プラグイン名 | 項目名 | 設定値 | 説明 |
---|---|---|---|
json | source | "message" |
message フィールドのテキストを JSON でパースします |
json | source | "[properties][AdditionalFields]" |
[properties][AdditionalFields] フィールドのテキストを JSON でパースします |
ruby | code | "event.get('properties').each {|k, v| event.set(k, v)} event.remove('properties')" | フィールド名に properties という文字列が含まれている場合は削除します |
date | match | ["Timestamp", "ISO8601"] |
Timestamp フィールドに含まれる ISO8601 形式の時刻情報を @timestamp フィールドに利用します |
date | timezone | "UTC" |
Timestamp フィールドに含まれる時刻情報のタイムゾーンは UTC になります |
mutate | remove_field | ["message", "[event][original]", "AdditionalFields"] | Elasticsearch に転送不要なフィールドを削除します |
【参考】
・JSON filter plugin(公式ページ)
・Ruby filter plugin(公式ページ)
・Date filter plugin(公式ページ)
・Mutate filter plugin(公式ページ)
2-3. output の設定
Elasticsearch へログを転送するための設定をおこないます。
logstash.conf
の output 句に以下の設定値を設定します。
output {
# output to Elasticsearch
elasticsearch {
hosts => ["https://10.0.4.104:9200"]
user => "elastic"
password => "**************"
ssl => true
ssl_certificate_verification => false
}
}
【設定内容】
プラグイン名 | 項目名 | 設定値 | 説明 |
---|---|---|---|
elasticsearch | hosts | ["https://10.0.4.104:9200"] | Elasticsearch ノードに TCP9200 ポートに HTTPS でログを転送します |
elasticsearch | user | "elastic" | Elasticsearch の認証用ユーザーとして elastic を利用します |
elasticsearch | password | "<elastic ユーザーのパスワード>" | 上記ユーザーのパスワードを指定します |
elasticsearch | ssl | true | HTTPS 通信のため、SSL 有効化します |
elasticsearch | ssl_certificate_verification | false | 自己証明書を利用しているため、証明書の検証を無効とします |
logstash.conf
を保存して閉じます。(:wq!
で vi エディタを閉じます)
【参考】
・Elasticsearch output plugin(公式ページ)
・Secure your connection to Elasticsearch(公式ページ)
3. Filebeat と Logstsh の起動
設定完了後、Logstash、Filebeat の順にプロセスを起動します。
$ sudo systemctl start logstash
$ sudo systemctl status logstash
$ sudo systemctl start filebeat
$ sudo systemctl status filebeat
4. ログの確認
最後に Kibana にログインし、意図した通りのログになっていることを確認します。
Kibana にログインし、[Disocver] を開き、ログのフィールドを確認します。
ログのサンプル
ログのサンプル(続き)
上記のような状態になっていれば完成です。
まとめ
いかがでしたでしょうか?
以前のブログ記事で書いた Elastic Agent を使う方法が新しい方式になりますが
依然として Filebeat を使ったアーキテクチャで運用されている企業も多くあることでしょう。
Filebeat を使わずに Logstash で直接 Event Hubs からログを取得する方法 [1] もあります。
Logstash で直接取得する方法は記事にしませんが、filter 句の内容はそのまま使えるはずです。
Elastic Agent を使った方式含め、Defender for Endpoint のデバイスログを有効活用する上で
皆様のお役に立てれば何よりです ^^
{
"_index": ".ds-logs-generic-default-2024.05.17-000001",
"_id": "XywZh48BwwfvYq_s0RV5",
"_version": 1,
"_score": 0,
"_source": {
"InitiatingProcessSignatureStatus": "Unknown",
"ProcessTokenElevation": "None",
"InitiatingProcessParentId": 0,
"SHA1": "12345a2cc321a77755cc2a888a747f8d1aa9cc99",
"ActionType": "ProcessCreated",
"InitiatingProcessId": 36366,
"AccountUpn": null,
"AppGuardContainerId": null,
"ProcessPosixFilePermissions": [
"None"
],
"InitiatingProcessIntegrityLevel": null,
"MachineGroup": null,
"InitiatingProcessVersionInfoOriginalFileName": null,
"InitiatingProcessVersionInfoCompanyName": null,
"ProcessCreationTime": "2024-05-17T15:05:11.32949Z",
"ProcessVersionInfoProductVersion": null,
"InitiatingProcessPosixSessionId": 1,
"InitiatingProcessAccountSid": "S-1-4-17",
"ProcessVersionInfoInternalFileName": null,
"FolderPath": "/usr/libexec/xpcproxy",
"ProcessVersionInfoProductName": null,
"ProcessPosixSessionId": 1,
"InitiatingProcessFolderPath": null,
"tags": [
"beats_input_codec_plain_applied"
],
"InitiatingProcessLogonId": 0,
"InitiatingProcessParentCreationTime": null,
"InitiatingProcessMD5": null,
"ProcessPosixProcessGroupId": 1,
"AccountName": "root",
"FileSize": 216400,
"InitiatingProcessSignerType": "Unknown",
"InitiatingProcessTokenElevation": "None",
"InitiatingProcessAccountUpn": null,
"InitiatingProcessVersionInfoFileDescription": null,
"InitiatingProcessSHA1": null,
"AccountDomain": "macbook-pro-2",
"InitiatingProcessParentFileName": "",
"DeviceId": "3212348ba2dbca444c3f4c4a1999cc1ca3cca5c9a",
"FileName": "xpcproxy",
"InitiatingProcessPosixEffectiveGroup": {
"PosixGroupId": 0,
"Name": "wheel"
},
"ProcessCurrentWorkingDirectory": "/",
"InitiatingProcessVersionInfoProductVersion": null,
"Timestamp": "2024-05-17T15:05:11.32949Z",
"InitiatingProcessCreationTime": "2024-05-17T15:05:11.2772Z",
"InitiatingProcessPosixProcessGroupId": 1,
"Tenant": "DefaultTenant",
"ProcessVersionInfoCompanyName": null,
"InitiatingProcessFileName": "",
"@version": "1",
"ProcessCommandLine": "xpcproxy com.apple.mdworker.shared.0C000000-0100-0000-0000-000000000000",
"InitiatingProcessCommandLine": "",
"event": {},
"LogonId": 0,
"ProcessVersionInfoFileDescription": null,
"AccountObjectId": null,
"ProcessPosixEffectiveGroup": {
"PosixGroupId": 0,
"Name": "wheel"
},
"InitiatingProcessAccountObjectId": null,
"InitiatingProcessAccountDomain": "macbook-pro-2",
"InitiatingProcessPosixEffectiveUser": {
"DomainName": "MacBook-Pro-2",
"PrimaryPosixGroup": {
"PosixGroupId": 0,
"Name": "wheel"
},
"PosixUserId": 0,
"LogonId": 0,
"Name": "root",
"Sid": "S-1-4-17"
},
"InitiatingProcessAccountName": "root",
"InitiatingProcessVersionInfoProductName": null,
"ReportId": 93974,
"operationName": "Publish",
"AccountSid": "S-1-4-17",
"InitiatingProcessFileSize": null,
"InitiatingProcessSHA256": null,
"SHA256": "aa15111c255028318071f3f99999ed0cbf99999aa7457555f257befbd3f15f8a",
"ProcessIntegrityLevel": null,
"@timestamp": "2024-05-17T15:05:11.329Z",
"InitiatingProcessVersionInfoInternalFileName": null,
"_TimeReceivedBySvc": "2024-05-17T15:05:49.3185222Z",
"data_stream": {
"namespace": "default",
"type": "logs",
"dataset": "generic"
},
"tenantId": "99aa44c2-cc2b-1111-a333-5b32a0c099a9",
"ProcessVersionInfoOriginalFileName": null,
"ProcessPosixEffectiveUser": {
"DomainName": "MacBook-Pro-2",
"PrimaryPosixGroup": {
"PosixGroupId": 0,
"Name": "wheel"
},
"PosixUserId": 0,
"LogonId": 0,
"Name": "root",
"Sid": "S-1-4-17"
},
"InitiatingProcessPosixRealUser": {
"DomainName": "MacBook-Pro-2",
"PrimaryPosixGroup": {
"PosixGroupId": 0,
"Name": "wheel"
},
"PosixUserId": 0,
"LogonId": 0,
"Name": "root",
"Sid": "S-1-4-17"
},
"time": "2024-05-17T15:08:42.1852239Z",
"ProcessId": 36366,
"category": "AdvancedHunting-DeviceProcessEvents",
"MD5": "c3a23c142242c80c8774455f5a88a9a9",
"DeviceName": "macbook-pro-2"
},
"fields": {
"InitiatingProcessSignatureStatus": [
"Unknown"
],
"ProcessTokenElevation": [
"None"
],
"InitiatingProcessParentId": [
0
],
"ActionType": [
"ProcessCreated"
],
"ProcessPosixEffectiveUser.Name": [
"root"
],
"SHA1": [
"12345a2cc321a77755cc2a888a747f8d1aa9cc99"
],
"InitiatingProcessId": [
36366
],
"InitiatingProcessPosixRealUser.LogonId": [
0
],
"InitiatingProcessPosixEffectiveUser.PrimaryPosixGroup.Name": [
"wheel"
],
"InitiatingProcessPosixRealUser.PrimaryPosixGroup.PosixGroupId": [
0
],
"InitiatingProcessPosixEffectiveUser.DomainName": [
"MacBook-Pro-2"
],
"ProcessPosixFilePermissions": [
"None"
],
"ProcessPosixEffectiveUser.PrimaryPosixGroup.Name": [
"wheel"
],
"InitiatingProcessPosixRealUser.PrimaryPosixGroup.Name": [
"wheel"
],
"ProcessPosixEffectiveUser.PrimaryPosixGroup.PosixGroupId": [
0
],
"InitiatingProcessPosixRealUser.Sid": [
"S-1-4-17"
],
"ProcessCreationTime": [
"2024-05-17T15:05:11.32949Z"
],
"InitiatingProcessPosixEffectiveUser.Name": [
"root"
],
"InitiatingProcessPosixEffectiveGroup.Name": [
"wheel"
],
"InitiatingProcessPosixSessionId": [
1
],
"InitiatingProcessAccountSid": [
"S-1-4-17"
],
"InitiatingProcessPosixRealUser.DomainName": [
"MacBook-Pro-2"
],
"FolderPath": [
"/usr/libexec/xpcproxy"
],
"ProcessPosixEffectiveUser.LogonId": [
0
],
"ProcessPosixSessionId": [
1
],
"data_stream.type": [
"logs"
],
"tags": [
"beats_input_codec_plain_applied"
],
"InitiatingProcessLogonId": [
0
],
"ProcessPosixEffectiveGroup.PosixGroupId": [
0
],
"ProcessPosixEffectiveUser.DomainName": [
"MacBook-Pro-2"
],
"ProcessPosixProcessGroupId": [
1
],
"ProcessPosixEffectiveGroup.Name": [
"wheel"
],
"AccountName": [
"root"
],
"FileSize": [
216400
],
"InitiatingProcessPosixEffectiveUser.LogonId": [
0
],
"InitiatingProcessPosixRealUser.Name": [
"root"
],
"InitiatingProcessPosixEffectiveUser.PrimaryPosixGroup.PosixGroupId": [
0
],
"InitiatingProcessSignerType": [
"Unknown"
],
"InitiatingProcessTokenElevation": [
"None"
],
"AccountDomain": [
"macbook-pro-2"
],
"DeviceId": [
"3212348ba2dbca444c3f4c4a1999cc1ca3cca5c9a"
],
"InitiatingProcessParentFileName": [
""
],
"FileName": [
"xpcproxy"
],
"ProcessCurrentWorkingDirectory": [
"/"
],
"InitiatingProcessPosixRealUser.PosixUserId": [
0
],
"Timestamp": [
"2024-05-17T15:05:11.32949Z"
],
"InitiatingProcessCreationTime": [
"2024-05-17T15:05:11.2772Z"
],
"InitiatingProcessPosixProcessGroupId": [
1
],
"ProcessPosixEffectiveUser.PosixUserId": [
0
],
"Tenant": [
"DefaultTenant"
],
"InitiatingProcessFileName": [
""
],
"ProcessPosixEffectiveUser.Sid": [
"S-1-4-17"
],
"@version": [
"1"
],
"InitiatingProcessCommandLine": [
""
],
"ProcessCommandLine": [
"xpcproxy com.apple.mdworker.shared.0C000000-0100-0000-0000-000000000000"
],
"LogonId": [
0
],
"InitiatingProcessPosixEffectiveUser.PosixUserId": [
0
],
"InitiatingProcessAccountDomain": [
"macbook-pro-2"
],
"data_stream.namespace": [
"default"
],
"InitiatingProcessAccountName": [
"root"
],
"InitiatingProcessPosixEffectiveGroup.PosixGroupId": [
0
],
"ReportId": [
93974
],
"operationName": [
"Publish"
],
"InitiatingProcessPosixEffectiveUser.Sid": [
"S-1-4-17"
],
"AccountSid": [
"S-1-4-17"
],
"SHA256": [
"aa15111c255028318071f3f99999ed0cbf99999aa7457555f257befbd3f15f8a"
],
"@timestamp": [
"2024-05-17T15:05:11.329Z"
],
"_TimeReceivedBySvc": [
"2024-05-17T15:05:49.3185222Z"
],
"data_stream.dataset": [
"generic"
],
"tenantId": [
"99aa44c2-cc2b-1111-a333-5b32a0c099a9"
],
"ProcessId": [
36366
],
"time": [
"2024-05-17T15:08:42.1852239Z"
],
"category": [
"AdvancedHunting-DeviceProcessEvents"
],
"DeviceName": [
"macbook-pro-2"
],
"MD5": [
"c3a23c142242c80c8774455f5a88a9a9"
]
}
}
Discussion