收集 Google App Engine 記錄

支援的國家/地區:

本文說明如何使用 Google Cloud Storage V2,將 Google App Engine 記錄檔擷取至 Google Security Operations。

Google App Engine 是全代管的無伺服器平台,可用於建構及部署網頁應用程式和 API。App Engine 會自動為 HTTP 要求產生要求記錄,並從您的程式碼產生應用程式記錄。這些記錄會傳送至 Cloud Logging,並可匯出至 Cloud Storage,以便擷取至 Google Security Operations。

事前準備

請確認您已完成下列事前準備事項:

  • Google SecOps 執行個體
  • 已啟用 Cloud Storage API 的 GCP 專案
  • 建立及管理 GCS 值區的權限
  • 管理 Google Cloud Storage 值區 IAM 政策的權限
  • 建立 Cloud Logging 接收器的權限 (roles/logging.configWriter)
  • 可用的 App Engine 應用程式 (標準或彈性環境)

建立 Google Cloud Storage 值區

  1. 前往 Google Cloud Console
  2. 選取專案或建立新專案。
  3. 在導覽選單中,依序前往「Cloud Storage」>「Bucket」
  4. 按一下「建立值區」
  5. 請提供下列設定詳細資料:

    設定
    為 bucket 命名 輸入全域不重複的名稱 (例如 appengine-logs-export)
    位置類型 根據需求選擇 (區域、雙區域、多區域)
    位置 選取位置 (例如 us-central1)
    儲存空間級別 標準 (建議用於經常存取的記錄)
    存取控管 統一 (建議)
    保護工具 選用:啟用物件版本管理或保留政策
  6. 點選「建立」

設定 Cloud Logging,將 App Engine 記錄匯出至 GCS

Cloud Logging 會使用記錄檔接收器,將記錄項目轉送至支援的目的地,包括 Cloud Storage 值區。接收器的寫入者身分必須具備目的地值區的 Storage 物件建立者角色 (roles/storage.objectCreator)。

建立 Cloud Logging 接收器

  1. Google Cloud 控制台中,依序前往「Logging」>「Log Router」
  2. 按一下「Create Sink」(建立接收器)
  3. 請提供下列設定詳細資料:
    • 接收器名稱:輸入描述性名稱 (例如 appengine-to-gcs)。
    • 接收器說明:選填說明。
  4. 點選「下一步」
  5. 在「選取接收器服務」部分:
    • 接收器服務:選取「Cloud Storage bucket」(Cloud Storage 值區)
    • 選取 Cloud Storage bucket:從下拉式選單中選取 appengine-logs-export
  6. 點選「下一步」
  7. 在「選擇要納入接收器的記錄檔」部分,輸入篩選查詢來選取 App Engine 記錄。資源類型必須與「gae_app」完全相同。

    所有 App Engine 記錄 (要求和應用程式記錄):

    resource.type="gae_app"
    

    僅限 App Engine 要求記錄:

    resource.type="gae_app"
    logName="projects/PROJECT_ID/logs/appengine.googleapis.com/request_log"
    

    App Engine 應用程式記錄 (stdout/stderr):

    resource.type="gae_app"
    (logName="projects/PROJECT_ID/logs/stdout" OR logName="projects/PROJECT_ID/logs/stderr")
    

    PROJECT_ID 替換為您的 GCP 專案 ID。

  8. 點選「下一步」

  9. 檢查設定,然後按一下「建立接收器」

授予接收器寫入者身分權限

建立接收器後,您必須在目的地 bucket 中,授予接收器的寫入者身分 Storage 物件建立者角色。服務帳戶的寫入者身分類似於:serviceAccount:service-123456789012@gcp-sa-logging.iam.gserviceaccount.com

  1. 在「記錄檔路由器」頁面中,找出新建立的接收器。
  2. 按一下接收器名稱旁的三點選單圖示。
  3. 選取「查看接收器詳細資料」
  4. 複製「寫入者身分」 (服務帳戶電子郵件地址)。
  5. 依序前往「Cloud Storage」>「Buckets」
  6. 按一下 bucket 名稱 (appengine-logs-export)。
  7. 前往「權限」分頁標籤。
  8. 按一下「授予存取權」
  9. 請提供下列設定詳細資料:
    • 新增主體:貼上接收器的寫入者身分 (服務帳戶電子郵件地址)。
    • 指派角色:選取「Storage 物件建立者」
  10. 按一下 [儲存]

擷取 Google SecOps 服務帳戶

Google SecOps 會使用專屬服務帳戶,從 GCS bucket 讀取資料。您必須授予這個服務帳戶值區存取權。

在 Google SecOps 中設定資訊提供,擷取 App Engine 記錄

  1. 依序前往「SIEM 設定」>「動態饋給」
  2. 按一下「新增動態消息」
  3. 按一下「設定單一動態饋給」
  4. 在「動態饋給名稱」欄位中輸入動態饋給名稱 (例如 App Engine Logs)。
  5. 選取「Google Cloud Storage V2」做為「來源類型」
  6. 選取「GCP_APP_ENGINE」做為「記錄類型」

  7. 按一下「取得服務帳戶」

  8. 系統會顯示不重複的服務帳戶電子郵件地址,例如:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. 複製這個電子郵件地址,後續步驟會用到。

  10. 點選「下一步」

  11. 指定下列輸入參數的值:

    • 儲存空間 bucket URL:輸入 GCS bucket URI,並加上前置路徑:

      gs://appengine-logs-export/
      

      Cloud Logging 會依記錄類型和日期,將匯出的記錄檔整理到目錄階層中。記錄類型可以是複合名稱,例如 appengine.googleapis.com/request_log。檔案會經過分片,並以時間範圍命名 (例如 08:00:00_08:59:59_S0.json)。

    • 來源刪除選項:根據偏好設定選取刪除選項:

      • 永不:移轉後一律不刪除任何檔案 (建議用於測試)。
      • 刪除已轉移的檔案:成功轉移檔案後刪除檔案。
      • 刪除已轉移的檔案和空白目錄:成功轉移後刪除檔案和空白目錄。
    • 檔案存在時間上限:包含在過去天數內修改的檔案。預設值為 180 天。

    • 資產命名空間資產命名空間

    • 擷取標籤:要套用至這個動態饋給事件的標籤。

  12. 點選「下一步」

  13. 在「Finalize」(完成) 畫面中檢查新的動態饋給設定,然後按一下「Submit」(提交)

將 IAM 權限授予 Google SecOps 服務帳戶

Google SecOps 服務帳戶需要 GCS bucket 的「Storage 物件檢視者」角色。

  1. 依序前往「Cloud Storage」>「Buckets」
  2. 按一下 bucket 名稱 (appengine-logs-export)。
  3. 前往「權限」分頁標籤。
  4. 按一下「授予存取權」
  5. 請提供下列設定詳細資料:
    • 新增主體:貼上 Google SecOps 服務帳戶電子郵件地址。
    • 指派角色:選取「Storage 物件檢視者」
  6. 按一下 [儲存]

瞭解 App Engine 記錄結構

App Engine 會自動將要求記錄和應用程式記錄傳送至 Cloud Logging。App Engine 會自動發出傳送至應用程式的要求記錄,因此您不需要編寫要求記錄。本節說明如何寫入應用程式記錄。

App Engine 要求記錄的記錄項目包含 protoPayload 欄位,這些欄位會保留 @type 為「type.googleapis.com/google.appengine.logging.v1.RequestLog」的 RequestLog 類型物件。資源類型為「gae_app」。

根據預設,記錄酬載是儲存在記錄項目 textPayload 欄位中的文字字串。這些字串會以訊息形式顯示在記錄檔探索器中,並與發出這些字串的 App Engine 服務和版本建立關聯。

如要寫入結構化記錄,請以單行序列化 JSON 格式寫入記錄。以 JSON 字典形式提供結構化記錄時,系統會從 jsonPayload 移除某些特殊欄位,然後寫入產生的 LogEntry 中的對應欄位。舉例來說,如果 JSON 包含嚴重程度屬性,系統會從 jsonPayload 移除該屬性,並改以記錄項目的嚴重程度顯示。

已知限制

將記錄從記錄接收器傳送至 Cloud Storage 時,Cloud Storage 目的地只會包含要求記錄。App Engine 會將應用程式記錄寫入不同資料夾。

系統會以每小時批次作業的形式,將轉送的記錄項目儲存至 Cloud Storage bucket。第一批項目可能需要 2 到 3 個小時才會開始出現。

在 App Engine 彈性環境中,記錄服務屬於自動處理的作業。只是收集記錄的格式有所不同。記錄不會與要求綑綁在一起,且 stdout 和 stderr 的記錄會分開收集。

UDM 對應表

記錄欄位 UDM 對應 邏輯
jsonPayload.logger、taskTypeName、jsonPayload.@type、jsonPayload.backendTargetProjectNumber、jsonPayload.cacheDecision、resource.labels.version_id、resource.labels.module_id、logName、spanId、trace、protoPayload.@type、labels.clone_id、operation.producer additional.fields 與從各個欄位建立的鍵/值標籤合併
中繼資料 中繼資料 從中繼資料重新命名
receiveTimestamp metadata.collected_timestamp 使用 RFC3339 的日期篩選器剖析
metadata.event_type 如果具有主體、目標和主體使用者,則設為「USER_LOGIN」;如果具有主體和目標,則設為「NETWORK_CONNECTION」;如果沒有主體但有目標,則設為「USER_UNCATEGORIZED」;如果具有主體,則設為「STATUS_UPDATE」;如果具有主體使用者,則設為「USER_UNCATEGORIZED」;否則設為「GENERIC_EVENT」
metadata.extensions.auth.type 如果具有 has_principal、has_target、has_principal_user,請設為「AUTHTYPE_UNSPECIFIED」
insertId metadata.product_log_id 直接複製值
httpRequest.requestMethod、protoPayload.method network.http.method httpRequest.requestMethod 中的值 (如不為空),否則為 protoPayload.method
httpRequest.userAgent network.http.parsed_user_agent 已轉換為 parseduseragent
httpRequest.status network.http.response_code 轉換為字串,然後轉換為整數
httpRequest.userAgent network.http.user_agent 直接複製值
httpRequest.responseSize network.received_bytes 已轉換為 uinteger
httpRequest.requestSize network.sent_bytes 已轉換為 uinteger
主體 主體 如果不是空白,則會從主體重新命名
protoPayload.host principal.asset.hostname 直接複製值
httpRequest.serverIp、protoPayload.ip principal.asset.ip 與 httpRequest.serverIp 或 protoPayload.ip 中的 server_ip 合併
protoPayload.host principal.hostname 直接複製值
httpRequest.serverIp、protoPayload.ip principal.ip 與 httpRequest.serverIp 或 protoPayload.ip 中的 server_ip 合併
protoPayload.appId principal.resource.attribute.labels 與包含鍵「appId」和欄位值的 appId_label 合併
requestUser principal.user.email_addresses 如果符合電子郵件模式,則與 requestUser 合併
security_result security_result 從 security_result 合併
resource.labels.forwarding_rule_name security_result.rule_labels 與包含「forwarding_rule_name」鍵和欄位值的 rule_label 合併
嚴重性 security_result.severity 如果符合 (?i)ERROR|CRITICAL,則設為嚴重性;如果符合 (?i)INFO,則設為資訊;如果符合 (?i)WARN,則設為中等;如果符合 (?i)DEBUG,則設為低;否則設為 UNKNOWN_SEVERITY
jsonPayload.statusDetails security_result.summary 直接複製值
目標 目標 如果目標不為空白,則會重新命名
resource.labels.backend_service_name target.application 直接複製值
httpRequest.remoteIp、jsonPayload.remoteIp target.asset.ip 與從 httpRequest.remoteIp 或 jsonPayload.remoteIp 擷取的 remote_ip 合併
resource.labels.project_id target.cloud.project.name 直接複製值
httpRequest.remoteIp、jsonPayload.remoteIp target.ip 與從 httpRequest.remoteIp 或 jsonPayload.remoteIp 擷取的 remote_ip 合併
resource.labels.zone target.resource.attribute.cloud.availability_zone 直接複製值
resource.labels.target_proxy_name、resource.labels.url_map_name target.resource.attribute.labels 與各來源的標籤合併
resource.type target.resource.type 直接複製值
httpRequest.requestUrl target.url 直接複製值
metadata.product_name 設為「GCP_APP_ENGINE」
metadata.vendor_name 設為「GCP」

還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。