セキュリティ分析情報用の SQL クエリ

このドキュメントでは、[ログ分析] ページで BigQuery 標準 SQL クエリを使用して Cloud Logging 監査ログを分析する方法について説明します。SQL クエリを使用すると、監査ログを集計して分析できます。このログは、Google Cloud リソースでの管理アクティビティとアクセスに関する情報を提供します。

監査ログについて

Google Cloud サービスで書き込むことができる監査ログには、次の 4 種類があります。

  • 管理アクティビティ監査ログ: 管理アクティビティ監査ログには、リソースの構成やメタデータを変更する API 呼び出しなどのアクションが記録されます。これらのログは常時書き込まれ、構成、除外、無効化はできません。

  • データアクセス監査ログ: データアクセス監査ログには、リソースの構成やメタデータを読み取る API 呼び出し、およびユーザーが指定したリソースデータの作成、変更、読み取りを行うユーザー駆動型の API 呼び出しが記録されます。データへのアクセスが頻繁に行われる API オペレーションであるため、これらのログはデフォルトで無効になっています(BigQuery を除く)。

  • システム イベント監査ログ: システム イベント監査ログには、リソースの構成を変更する Google Cloud のアクションのログエントリが含まれます。これらのログは、Google システムによって生成されるものであり、ユーザーの操作で生成されるものではありません。システム イベント監査ログを構成、除外、無効化することはできません。

  • ポリシー拒否監査ログ: セキュリティ ポリシー違反が原因で、Google Cloud サービスがユーザーやサービス アカウントへのアクセスを拒否した場合は、ポリシー拒否監査ログが記録されます。これらのログを無効にすることはできませんが、除外フィルタを使用して Logging への格納を防ぐことはできます。

監査ログの詳細については、監査ログの概要をご覧ください。監査ログと統合されたサービスの一覧については、監査ログを備えた Google Cloud サービスをご覧ください。

監査ログを使用してポリシー違反や不審なアクティビティを特定する

監査ログを使用して、ポリシー違反や不審なアクティビティを特定できます。

  • Identity and Access Management(IAM)の使用による潜在的な権限昇格、または Logging の無効化による防御回避を特定するには、管理アクティビティ監査ログを使用します。このような状況を特定するサンプルクエリについては、Logging 設定の変更をご覧ください。

  • API の不正使用、または Cloud Storage や BigQuery などのサービスでホストされているデータの不正使用を特定するには、データアクセス監査ログを使用します。このような状況を特定するサンプルクエリについては、プリンシパルによる API の大量使用を特定するをご覧ください。

  • データへのアクセス頻度とユーザーを特定する場合は、すべての監査ログに対してクエリを実行します。このような状況を特定するサンプルクエリについては、過去 1 か月間に実行された最も一般的なアクションを特定するをご覧ください。

準備

  • 監査ログを生成する Google Cloud プロジェクト、フォルダ、または組織があることを確認します。

  • 監査ログの転送先となるログバケットのビューにアクセスできることを確認します。ログ分析を使用するには、ログバケットをアップグレードする必要があります。ログ分析を使用するためにアップグレードされたログバケットの作成方法については、ログバケットを構成するをご覧ください。

  • シンクを作成してログを表示するために必要な権限を取得するには、次の IAM ロールを付与するよう管理者に依頼してください。

    ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。

    必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

    表示する監査ログによっては、独自のロールまたは権限が必要になる場合があります。IAM ロールの設定については、Logging の IAM によるアクセス制御のドキュメントをご覧ください。

  • [ログ分析] ページでこのドキュメントのクエリを使用するには、次の操作を行います。

    1. Google Cloud コンソールで、[ログ分析] ページに移動します。

      [ログ分析] に移動

      検索バーを使用してこのページを検索する場合は、小見出しが [Logging] である結果を選択します。

    2. クエリを実行するログビューのテーブル名を特定します。

      この名前を確認するには、[ログビュー] リストに移動して、ログビューを見つけて、[クエリ] を選択します。[クエリ] ペインには、クエリ対象のログビューのテーブル名を含むデフォルトのクエリが入力されます。 テーブル名の形式は project_ID.region.bucket_ID.view_ID です。

      デフォルトのクエリにアクセスする方法については、ログビューをクエリするをご覧ください。

    3. TABLE_NAME_OF_LOG_VIEW は、クエリを実行するログビューのテーブル名に置き換えてから、クエリをコピーします。

    4. クエリを [クエリ] ペインに貼り付けて [クエリを実行] をクリックします。

サンプルクエリ

このセクションでは、監査ログをクエリするサンプル SQL クエリを示します。

Logging の設定に対する変更

監査ログが無効になっているタイミング、またはデフォルトの Logging 設定が変更されたタイミングを特定するには、管理アクティビティ監査ログに対してクエリを実行します。

SELECT
  receive_timestamp, timestamp AS eventTimestamp,
  proto_payload.audit_log.request_metadata.caller_ip,
  proto_payload.audit_log.authentication_info.principal_email,
  proto_payload.audit_log.resource_name,
  proto_payload.audit_log.method_name
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  proto_payload.audit_log.service_name = "logging.googleapis.com"
  AND log_id = "cloudaudit.googleapis.com/activity"

過去 1 か月間に実行された最も一般的なアクションを特定する

過去 30 日間に最も一般的に実行されたアクションを特定するには、すべての監査ログにクエリを実行します。

SELECT
  proto_payload.audit_log.method_name,
  proto_payload.audit_log.service_name,
  resource.type,
  COUNT(*) AS counter
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND log_id="cloudaudit.googleapis.com/data_access"
GROUP BY
  proto_payload.audit_log.method_name,
  proto_payload.audit_log.service_name,
  resource.type
ORDER BY
  counter DESC
LIMIT 100

上記のクエリは、過去 30 日間のすべての監査ログを検索して、実行回数の多い 100 個のアクションを、method_nameservice_name リソースタイプ、実行されたアクションのカウンタに関する情報とともに返します。

サービス アカウントに付与されたロールを検出する

サービス アカウントの権限借用やサービス アカウントに付与されているロールを特定するには、管理アクティビティ監査ログに対してクエリを実行します。

SELECT
  timestamp,
  proto_payload.audit_log.authentication_info.principal_email as grantor,
  JSON_VALUE(bindingDelta.member) as grantee,
  JSON_VALUE(bindingDelta.role) as role,
  proto_payload.audit_log.resource_name,
  proto_payload.audit_log.method_name
FROM
  `TABLE_NAME_OF_LOG_VIEW`,
  UNNEST(JSON_QUERY_ARRAY(proto_payload.audit_log.service_data.policyDelta.bindingDeltas)) AS bindingDelta
WHERE
  timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
  AND log_id = "cloudaudit.googleapis.com/activity"
  AND (
    (resource.type = "service_account"
    AND proto_payload.audit_log.method_name LIKE "google.iam.admin.%.SetIAMPolicy")
    OR
    (resource.type IN ("project", "folder", "organization")
    AND proto_payload.audit_log.method_name = "SetIamPolicy"
    AND JSON_VALUE(bindingDelta.role) LIKE "roles/iam.serviceAccount%")
  )
  AND JSON_VALUE(bindingDelta.action) = "ADD"
  -- Principal (grantee) exclusions
  AND JSON_VALUE(bindingDelta.member) NOT LIKE "%@example.com"
ORDER BY
  timestamp DESC

上記のクエリは、監査ログを検索してサービス アカウントのプリンシパルに付与されているロールをキャプチャします。サービス アカウント トークン作成者のロールを使用すると、プリンシパルがサービス アカウントの権限を借用できます。このクエリでは、過去 7 日間の期間も指定し、承認された譲受人(%@example.com)は除外されます。

プリンシパルによる API の大量使用を特定する

プリンシパルによる使用量が異常に多い API を特定するには、すべての監査ログに対してクエリを実行します。

SELECT
  *
FROM (
  SELECT
    *,
    AVG(counter) OVER (
      PARTITION BY principal_email
      ORDER BY day
      ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS avg,
    STDDEV(counter) OVER (
      PARTITION BY principal_email
      ORDER BY day
      ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS stddev,
    COUNT(*) OVER (
      PARTITION BY principal_email
      RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS numSamples
  FROM (
    SELECT
      proto_payload.audit_log.authentication_info.principal_email,
      EXTRACT(DATE FROM timestamp) AS day,
      ARRAY_AGG(DISTINCT proto_payload.audit_log.method_name IGNORE NULLS) AS actions,
      COUNT(*) AS counter
    FROM `TABLE_NAME_OF_LOG_VIEW`
    WHERE
      timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 60 DAY)
      AND proto_payload.audit_log.authentication_info.principal_email IS NOT NULL
      AND proto_payload.audit_log.method_name NOT LIKE "storage.%.get"
      AND proto_payload.audit_log.method_name NOT LIKE "v1.compute.%.list"
      AND proto_payload.audit_log.method_name NOT LIKE "beta.compute.%.list"
    GROUP BY
      proto_payload.audit_log.authentication_info.principal_email,
      day
  )
)
WHERE
  counter > avg + 3 * stddev
  AND day >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
ORDER BY
  counter DESC

指定されたプリンシパル principal_email に対して、クエリは 1 日あたりの平均 API 呼び出し回数とそれらの API 呼び出しの標準偏差を計算します。API 呼び出し回数の平均値が移動平均と標準偏差の 3 倍より大きい場合、クエリには次の情報が表示されます。

  • 実行されたアクションのカウンタ。
  • 1 日に実行されたアクション数の平均計算値。
  • 実行された特定のアクション数。

次のステップ