AQ Tech Blog

OpenSearchの監査ログ出力の注意点

作成者: tsuyoshi.watanabe|2023年11月15日

はじめに

クラウドインテグレーション部の渡邊です。
今回は、AWS OpenSearchの監査ログの出力について説明します。
AWS OpenSearchが出力可能なログは以下4種類です。

  • インデックススローログ(ドキュメントの追加・削除・更新)
  • 検索スローログ(検索クエリ)
  • エラーログ(WARN, ERROR, FATAL, DEBUG の例外)
  • 監査ログ

その中で、スローログや監査ログは、OpenSearch Dashboards側で追加の設定が必要になります。
今回は、監査ログに絞って説明します。
スローログについては「OpenSearchのスローログ設定時の注意点」で紹介しています。

監査ログは、CloudWatchおよびOpenSearch Dashboardsで設定する必要があるので、注意が必要です(ドメインのCloudWatch設定の説明は割愛しております)。
公式ドキュメントにも、監査ログの設定に関して、以下の記載がありました。

監査ログの有効化は、2 段階のプロセスです。まず、CloudWatch Logs に CloudWatch Logs に監査ログを発行するようにドメインを設定します。次に、OpenSearch Dashboards で監査ログを有効にして、ニーズを満たすように監査ログを設定します。

引用元:監査ログ記録の有効化

環境情報

  • OpenSearch 2.7
  • Amazon Linux 2023

やってみた

事前に以下環境変数を設定してください。

USERNAME=<マスターユーザ名>
PASSWORD=<マスターユーザパスワード>
ENDPOINT=<OpenSearchエンドポイント>

まずは、デフォルトの設定を確認します。

$ curl -XGET -u "${USERNAME}:${PASSWORD}"  -H "Content-Type: application/json"  "https://${ENDPOINT}/_plugins/_security/api/audit?pretty"
{
  "_readonly" : [
    "/audit/exclude_sensitive_headers",
    "/compliance/internal_config",
    "/compliance/external_config"
  ],
  "config" : {
    "compliance" : {
      "enabled" : true,
      "write_log_diffs" : false,
      "read_watched_fields" : { },
      "read_ignore_users" : [ ],
      "write_watched_indices" : [ ],
      "write_ignore_users" : [ ],
      "read_metadata_only" : true,
      "write_metadata_only" : true,
      "external_config" : false,
      "internal_config" : true
    },
    "enabled" : false,
    "audit" : {
      "ignore_users" : [ ],
      "ignore_requests" : [ ],
      "disabled_rest_categories" : [
        "AUTHENTICATED",
        "GRANTED_PRIVILEGES"
      ],
      "disabled_transport_categories" : [
        "AUTHENTICATED",
        "GRANTED_PRIVILEGES"
      ],
      "log_request_body" : false,
      "resolve_indices" : true,
      "resolve_bulk_requests" : false,
      "exclude_sensitive_headers" : true,
      "enable_transport" : false,
      "enable_rest" : true
    }
  }
}

config直下のenabledfalseなので、無効であることがわかります。
実際に有効化して、設定します。
設定する場合と確認する場合(GETとPUT)で、リクエストするパスが異なるため注意してください。

$ curl -XPUT -u "${USERNAME}:${PASSWORD}"  -H "Content-Type: application/json"  "https://${ENDPOINT}/_plugins/_security/api/audit/config" -d \
'{
    "compliance" : {
      "enabled" : false,
      "write_log_diffs" : false,
      "read_watched_fields" : { },
      "read_ignore_users" : [ ],
      "write_watched_indices" : [ ],
      "write_ignore_users" : [ ],
      "read_metadata_only" : false,
      "write_metadata_only" : false,
      "external_config" : false,
      "internal_config" : true
    },
    "enabled" : true,
    "audit" : {
      "ignore_users" : [ ],
      "ignore_requests" : [ ],
      "disabled_rest_categories" : [
          "GRANTED_PRIVILEGES"
      ],
      "disabled_transport_categories" : [
          "GRANTED_PRIVILEGES",
          "INDEX_EVENT"
      ],
      "log_request_body" : true,
      "resolve_indices" : true,
      "resolve_bulk_requests" : true,
      "exclude_sensitive_headers" : true,
      "enable_transport" : true,
      "enable_rest" : true
    }
}'

{"status":"OK","message":"'config' GEdated."}

設定ができているか確認します。

$ curl -XGET -u "${USERNAME}:${PASSWORD}"  -H "Content-Type: application/json"  "https://${ENDPOINT}/_plugins/_security/api/audit?pretty"
{
  "_readonly" : [
    "/audit/exclude_sensitive_headers",
    "/compliance/internal_config",
    "/compliance/external_config"
  ],
  "config" : {
    "compliance" : {
      "enabled" : false,
      "write_log_diffs" : false,
      "read_watched_fields" : { },
      "read_ignore_users" : [ ],
      "write_watched_indices" : [ ],
      "write_ignore_users" : [ ],
      "read_metadata_only" : false,
      "write_metadata_only" : false,
      "external_config" : false,
      "internal_config" : true
    },
    "enabled" : true,
    "audit" : {
      "ignore_users" : [ ],
      "ignore_requests" : [ ],
      "disabled_rest_categories" : [
        "GRANTED_PRIVILEGES"
      ],
      "disabled_transport_categories" : [
        "GRANTED_PRIVILEGES",
        "INDEX_EVENT"
      ],
      "log_request_body" : true,
      "resolve_indices" : true,
      "resolve_bulk_requests" : true,
      "exclude_sensitive_headers" : true,
      "enable_transport" : true,
      "enable_rest" : true
    }
  }
}

設定が想定通りにできていました。
CloudWatchLogsの監査ログ/aws/OpenSearchService/domains/<ドメイン名>/audit-logsを確認してみると・・・

{
    "audit_cluster_name": "XXXXXXXXXXXX:<ドメイン名>",
    "audit_rest_request_params": {
        "pretty": ""
    },
    "audit_node_name": "5f89e3ec7c749a982790d6d3040ce489",
    "audit_request_initiating_user": "watanabe",
    "audit_rest_request_method": "GET",
    "audit_category": "AUTHENTICATED",
    "audit_request_origin": "REST",
    "audit_node_id": "yx1Dpkf9TAifQDEDU1TPtQ",
    "audit_request_layer": "REST",
    "audit_rest_request_path": "/_plugins/_security/api/audit",
    "@timestamp": "2023-08-30T12:04:55.084+00:00",
    "audit_request_effective_user_is_admin": false,
    "audit_format_version": 4,
    "audit_request_remote_address": "__IP__",
    "audit_rest_request_headers": {
        "Accept": [
            "*/*"
        ],
        "Connection": [
            "close"
        ],
        "User-Agent": [
            "curl/8.0.1"
        ],
        "Host": [
            "<ドメイン名>"
        ],
        "Content-Type": [
            "application/json"
        ]
    },
    "audit_request_effective_user": "watanabe"
}

出てました!

監査ログの設定値の考慮点

監査ログの設定値に関して、少なくとも3点留意する必要があります。

    1. 設定変更ができない項目がある(readonlyの設定項目がある)
    1. 大量のログが出る項目は無効にすることを検討する
    1. コンプライアンス設定の有無

 

1. 設定変更ができない項目がある(readonlyの設定項目がある)

設定変更ができない箇所の値を変更しようとすると、エラーが発生します。
設定変更ができないものは下表の通りです。

readonly設定 デフォルト
/audit/exclude_sensitive_headers true
/compliance/internal_config true
/compliance/external_config false

こちらの値を更新しようとすると、CONFLICT エラーとなるため注意しましょう。
以下リクエストでは、internal_configのデフォルト値を変更しようとしました。

$ curl -XPUT -u "${USERNAME}:${PASSWORD}"  -H "Content-Type: application/json"  "https://${ENDPOINT}/_plugins/_security/api/audit/config" -d \
'{
  "enabled": true,
  "audit": {
    "enable_rest": true,
    "disabled_rest_categories": [],
    "enable_transport": true,
    "disabled_transport_categories": [],
    "resolve_bulk_requests": true,
    "log_request_body": true,
    "resolve_indices": true,
    "exclude_sensitive_headers": true,
    "ignore_users": [],
    "ignore_requests": []
  },
  "compliance": {
    "enabled": false,
    "internal_config": false,
    "external_config": false,
    "read_metadata_only": false,
    "read_watched_fields": {},
    "read_ignore_users": [],
    "write_metadata_only": false,
    "write_log_diffs": false,
    "write_watched_indices": [],
    "write_ignore_users": []
  }
}'
{"status":"CONFLICT","message":"Attempted to update read-only property."}

 

2. 大量のログが出る項目は無効にすることを検討する

ログが大量に出る項目をtrueにすると、コストやログの発見のしやすさにおいて、問題になる可能性があります。
AWS側でもGRANTED_PRIVILEGES  AUTHENTICATED無効化を推奨しているため、成功したログを記録する必要がなければ無効にしてよいと思います。 今回はログをすぐに確認したかったため、AUTHENTICATEDを有効にしております。
なお、INDEX_EVENTも大量に出たため無効にしました。

GRANTED_PRIVILEGES と AUTHENTICATED を除外カテゴリのままにしておくことを強くお勧めします

引用元:Monitoring audit logs in Amazon OpenSearch Service

 

3. コンプライアンス設定の有無

コンプライアンス設定を有効にすることで、フィールドレベルなどの、より細かい単位でロギングできることがメリットです。

コンプライアンス設定では、インデックス、ドキュメント、またはフィールドレベルのアクセスを調整できます。

よって、ロギングする粒度次第で、コンプライアンス設定の有効化を検討するとよいと思います。

まとめ

  • 監査ログの設定・確認でリクエストするパスは異なる
  • 監査ログには設定変更ができない項目がある
  • フィールドカテゴリーすべてを有効化してしまうと大量にログが出力されてしまうため適切な対象に絞る方がよい
  • ロギングする粒度を考慮してコンプライアンス設定の有無を検討する

【参考】

監査ログ記録の有効化

監査ログ

Audit logs

コンプライアンス設定