用於安全性洞察的 SQL 查詢

本文件說明如何在「Log Analytics」頁面中使用 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 專案、資料夾或機構。

  • 請確認您有權存取稽核記錄會導向的記錄值區。您必須升級記錄檔值區,才能使用 Log Analytics。如要瞭解如何建立已升級為使用 Log Analytics 的記錄檔值區,請參閱「設定記錄檔值區」。

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

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

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

    視您要查看哪些稽核記錄而定,可能需要不同的角色或權限。如要瞭解如何設定 IAM 角色,請參閱「使用 IAM 控管存取權」說明文件。

  • 如要在「Log Analytics」頁面中使用本文件中的查詢,請執行下列操作:

    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 異常頻繁的使用者,請查詢所有稽核記錄:

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 呼叫的平均次數大於總平均值加上標準差的三倍,查詢會顯示下列資訊:

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

後續步驟