用於安全性洞察的 SQL 查詢

本文說明如何使用記錄檔分析頁面的 BigQuery 標準 SQL 查詢,分析 Cloud Logging 稽核記錄。您可以透過 SQL 查詢匯總及分析稽核記錄,瞭解 Google Cloud 資源中的管理活動和存取權。

關於稽核記錄

服務可寫入四種類型的稽核記錄: Google Cloud

  • 管理員活動稽核記錄:管理員活動稽核記錄會記錄 API 呼叫,或修改設定或資源中繼資料的其他動作。系統一律會寫入這些記錄,且該記錄無法設定、排除或停用。

  • 資料存取稽核記錄:資料存取稽核記錄會記錄讀取資源設定或中繼資料的 API 呼叫,以及建立、修改或讀取使用者所提供資源資料的使用者驅動 API 呼叫。由於存取資料是常見的 API 作業,因此這些記錄預設為停用 (BigQuery 除外)。

  • 系統事件稽核記錄:系統事件稽核記錄包含修改資源設定的動作記錄項目。Google Cloud 這些記錄是由 Google 系統產生,而不是由使用者動作產生。您無法設定、排除或停用系統事件稽核記錄。

  • 政策拒絕稽核記錄:當 Google Cloud 服務因違反安全性政策而拒絕使用者或服務帳戶存取權時,系統會記錄政策拒絕稽核記錄。您無法停用這些記錄,但可以使用排除篩選器,防止這些記錄儲存在 Logging 中。

如要進一步瞭解稽核記錄,請參閱稽核記錄總覽。 如需與稽核記錄整合的服務清單,請參閱Google Cloud 含有稽核記錄的服務

使用稽核記錄找出違規或可疑活動

您可以透過稽核記錄找出違規政策或可疑活動:

  • 如要使用 Identity and Access Management (IAM) 找出潛在的權限提升問題,或是透過停用記錄功能來規避防禦措施,請使用管理員活動稽核記錄。如需可識別此情境的範例查詢,請參閱「記錄設定的異動」。

  • 如要找出 API 的潛在誤用情形,或 Cloud Storage 或 BigQuery 等服務中代管的資料,請使用資料存取稽核記錄。如需識別這類情況的範例查詢,請參閱「識別主體的高 API 使用量」。

  • 如要瞭解資料的存取頻率和存取者,請查詢所有稽核記錄。如需識別這種情況的範例查詢,請參閱「判斷過去一個月內最常執行的動作」。

事前準備

  • 請確認您有產生稽核記錄的 Google Cloud 專案、資料夾或機構。

  • 確認您有權存取稽核記錄檔的記錄檔 bucket 檢視畫面。您必須升級記錄檔 bucket,才能使用記錄檔分析。如要瞭解如何建立已升級的記錄檔 bucket,以使用記錄檔分析工具,請參閱「設定記錄檔 bucket」。

  • 如要取得建立接收器和查看記錄所需的權限,請要求管理員授予下列 IAM 角色:

    • 您專案的「記錄設定寫入者」 (roles/logging.configWriter) 權限
    • 專案的「記錄檢視器」 (roles/logging.viewer)

    如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

    您或許還可透過自訂角色或其他預先定義的角色取得必要權限。

    您可能需要不同的角色或權限,才能查看特定稽核記錄。如要瞭解如何設定 IAM 角色,請參閱 Logging 使用 IAM 控管存取權的相關說明文件。

  • 如要在「記錄檔分析」頁面中使用本文中的查詢,請按照下列步驟操作:

    1. 在 Google Cloud 控制台中,前往「Log Analytics」(記錄檔分析) 頁面:

      前往「Log Analytics」(記錄檔分析)

      如果您是使用搜尋列尋找這個頁面,請選取子標題為「Logging」的結果

    2. 找出要查詢的記錄檢視畫面資料表名稱。

      如要找出這個名稱,請前往「記錄檢視畫面」清單,找出記錄檢視畫面,然後選取「查詢」。「查詢」窗格會填入預設查詢,其中包含所查詢記錄檢視區塊的資料表名稱。資料表名稱的格式為 project_ID.region.bucket_ID.view_ID

      如要進一步瞭解如何存取預設查詢,請參閱「查詢記錄檢視區塊」。

    3. TABLE_NAME_OF_LOG_VIEW 替換為要查詢的記錄檢視畫面資料表名稱,然後複製查詢。

    4. 在「Query」(查詢) 窗格中貼上查詢,然後點選「Run query」(執行查詢)

查詢範例

本節提供查詢稽核記錄的 SQL 查詢範例。

記錄設定異動

如要瞭解稽核記錄何時停用,或預設記錄設定何時變更,請查詢管理員活動稽核記錄:

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"

判斷過去一個月內最常執行的動作

如要找出過去 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

先前的查詢會搜尋稽核記錄,擷取授予服務帳戶主體的角色。「服務帳戶權杖建立者」角色可讓主體模擬服務帳戶。這項查詢也會指定過去七天的時間範圍,並排除已核准的受助者 (%@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,查詢會計算每天的平均 API 呼叫次數,以及這些 API 呼叫的標準差。如果 API 呼叫的平均次數大於執行平均值加上三倍標準差,查詢就會顯示下列資訊:

  • 已執行的動作計數器。
  • 系統計算出的每日平均動作次數。
  • 執行的具體動作。

後續步驟