クラウドインテグレーション部の渡邊です。
今回は、AWS OpenSearchの監査ログの出力について説明します。
AWS OpenSearchが出力可能なログは以下4種類です。
その中で、スローログや監査ログは、OpenSearch Dashboards側で追加の設定が必要になります。
今回は、監査ログに絞って説明します。
スローログについては「OpenSearchのスローログ設定時の注意点」で紹介しています。
監査ログは、CloudWatchおよびOpenSearch Dashboardsで設定する必要があるので、注意が必要です(ドメインのCloudWatch設定の説明は割愛しております)。
公式ドキュメントにも、監査ログの設定に関して、以下の記載がありました。
監査ログの有効化は、2 段階のプロセスです。まず、CloudWatch Logs に CloudWatch Logs に監査ログを発行するようにドメインを設定します。次に、OpenSearch Dashboards で監査ログを有効にして、ニーズを満たすように監査ログを設定します。
引用元:監査ログ記録の有効化
事前に以下環境変数を設定してください。
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直下のenabledがfalseなので、無効であることがわかります。
実際に有効化して、設定します。
設定する場合と確認する場合(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点留意する必要があります。
設定変更ができない箇所の値を変更しようとすると、エラーが発生します。
設定変更ができないものは下表の通りです。
| 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."}
ログが大量に出る項目をtrueにすると、コストやログの発見のしやすさにおいて、問題になる可能性があります。
AWS側でもGRANTED_PRIVILEGES と AUTHENTICATED無効化を推奨しているため、成功したログを記録する必要がなければ無効にしてよいと思います。 今回はログをすぐに確認したかったため、AUTHENTICATEDを有効にしております。
なお、INDEX_EVENTも大量に出たため無効にしました。
GRANTED_PRIVILEGES と AUTHENTICATED を除外カテゴリのままにしておくことを強くお勧めします
引用元:Monitoring audit logs in Amazon OpenSearch Service
コンプライアンス設定を有効にすることで、フィールドレベルなどの、より細かい単位でロギングできることがメリットです。
コンプライアンス設定では、インデックス、ドキュメント、またはフィールドレベルのアクセスを調整できます。
よって、ロギングする粒度次第で、コンプライアンス設定の有効化を検討するとよいと思います。
【参考】