Elasticsearchで実行されている検索クエリーを監査ログで確認する方法

#　はじめに
監査目的などでElasticsearchに対して発行されているクエリーを記録したい場合、監査ログを有効化すれば可能です。
本記事ではその手順についてまとめました。今回はElastic Cloudを利用した前提の手順となっています。

# 手順
- 最初にElastic Cloudの管理コンソールのLogs and metricsから、ログのStack Monitoringを有効化する必要があります。
以下は有効化後の画面例です。（モニタリングデータ送信先のDeploymentは自身のDeploymentへの送信でも動きます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/557d08a2-4d01-957e-94e1-543528b23916.png)

- 次に、Elasticsearchのuser settingsを編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/f7bb5375-a964-768a-ffd8-5141a87a3c25.png)


- 監査ログを有効化してさらに検索クエリーの詳細を出力するためには、以下のように３行追加してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/11805e32-d6f7-1b55-cc71-9b1366cdfc9d.png)

```
xpack.security.audit.enabled: true
xpack.security.audit.logfile.events.emit_request_body: true
xpack.security.audit.logfile.events.include: _all
```

補足：あるいは以下のようにevents.actionタイプを_allから特定のイベントに絞ってもOKです。（クエリーの詳細はこのevent.actionがauthentication_successのログに記録されます）
xpack.security.audit.logfile.events.include: authentication_success

- Kibana内でStack Monitoringの画面を開き、Logsのボックスを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/e6b405ea-eb64-ac39-5bf6-14b38aaa9d3f.png)

- Auditログが表示されますが、詳しく見るためには下に見えるLogsビューのリンクをクリックしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/e110cda3-2a89-0222-c80d-d367bb46d266.png)

- Logsビューでは、Elasticsearchのログ全般が表示されますが、多くのログが表示されるので絞り込むために検索ボックスに条件を追加します。
http.request.body_contentのフィールドが存在するもので絞り込むと、検索リクエストのボディが含まれるデータだけ絞り込みできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/1d1b093e-ba9a-e0c2-2d32-c6575c7b7591.png)

詳細を見てクエリー内容が見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109197/3920414c-4a9c-1a4d-5428-5a6e04fb4b02.png)

この例で見えるクエリーのURLと、ボディの一例は以下の通りです。

**user.name:**
2770367626

**url.original:**
/kibana_sample_data_flights/_async_search?batched_reduce_size=64&ccs_minimize_roundtrips=true&wait_for_completion_timeout=200ms&keep_on_completion=true&keep_alive=60000ms&ignore_unavailable=true&preference=1724807312742


**http.request.body.content:**
```json:クエリーのボディ
{
	"sort": [
		{
			"timestamp": {
				"order": "desc",
				"format": "strict_date_optional_time",
				"unmapped_type": "boolean"
			}
		},
		{
			"_doc": {
				"order": "desc",
				"unmapped_type": "boolean"
			}
		}
	],
	"fields": [
		{
			"field": "*",
			"include_unmapped": "true"
		},
		{
			"field": "timestamp",
			"format": "strict_date_optional_time"
		}
	],
	"size": 500,
	"version": true,
	"script_fields": {},
	"stored_fields": [
		"*"
	],
	"runtime_mappings": {
		"hour_of_day": {
			"type": "long",
			"script": {
				"source": "emit(doc['timestamp'].value.getHour());"
			}
		}
	},
	"_source": false,
	"query": {
		"bool": {
			"must": [
				{
					"query_string": {
						"query": "AvgTicketPrice:(>=10 AND <444) AND Cancelled:true",
						"analyze_wildcard": true,
						"time_zone": "Asia/Tokyo"
					}
				}
			],
			"filter": [
				{
					"range": {
						"timestamp": {
							"format": "strict_date_optional_time",
							"gte": "2024-08-28T02:07:02.317Z",
							"lte": "2024-08-28T02:22:02.317Z"
						}
					}
				}
			],
			"should": [],
			"must_not": []
		}
	},
	"highlight": {
		"pre_tags": [
			"@kibana-highlighted-field@"
		],
		"post_tags": [
			"@/kibana-highlighted-field@"
		],
		"fields": {
			"*": {}
		},
		"fragment_size": 2147483647
	},
	"track_total_hits": false
}
```

# おわり
本番環境では非常に多くの監査ログが生成されるので、気をつけて限定的に使っていただければと思います。