收集 Google App Engine 記錄

剖析器版本:3.0

支援:

本文說明如何使用 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 bucket 的權限
  • 管理 GCS bucket IAM 政策的權限
  • 建立 Cloud Logging 記錄檔接收器的權限 (roles/logging.configWriter)
  • 有效的 App Engine 應用程式 (標準或彈性環境)

建立 Google Cloud Storage bucket

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

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

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

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

建立 Cloud Logging 記錄檔接收器

  1. 在 Google Cloud 控制台中,依序前往「Logging」 >「Log Router」。
  2. 按一下「Create Sink」(建立接收器)。
  3. 請提供下列設定詳細資料:
    • 「Sink name」(接收器名稱):輸入描述性名稱 (例如 appengine-to-gcs)。
    • 接收器說明:選填說明。
  4. 點選「下一步」。
  5. 在「選取接收器服務」部分:
    • 接收器服務:選取「Cloud Storage bucket」。
    • 選取 Cloud Storage bucket:從下拉式選單中選取 appengine-logs-export。
  6. 點選「下一步」。
  7. 在「Choose logs to include in sink」(選擇要納入接收器的記錄檔) 部分,輸入篩選器查詢來選取 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. 在「Log Router」(記錄檔路由器) 頁面中,找出新建立的接收器。
  2. 按一下接收器名稱旁的選單圖示 (三個垂直點)。
  3. 選取「查看接收器詳細資料」。
  4. 複製寫入者身分 (服務帳戶電子郵件地址)。
  5. 依序前往「Cloud Storage」 > 「Bucket」。
  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. 在「Feed name」(動態饋給名稱) 欄位中,輸入動態饋給名稱 (例如 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 網址:輸入 GCS bucket URI,並加上前置路徑:

      gs://appengine-logs-export/
      

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

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

      • Never:轉移後一律不刪除任何檔案 (建議用於測試)。
      • 刪除已轉移的檔案:成功轉移檔案後刪除檔案。
      • 刪除已轉移的檔案和空目錄:成功轉移後,刪除檔案和空目錄。
    • 檔案存在時間上限:包含過去幾天內修改過的檔案。預設為 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 欄位,該欄位含有 RequestLog 類型的物件,其 @type 為「type.googleapis.com/google.appengine.logging.v1.RequestLog」。資源類型為「gae_app」。

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

如要寫入結構化記錄,請以單行序列化 JSON 的形式寫入記錄。以 JSON 字典形式提供結構化記錄時,系統會從 jsonPayload 中移除某些特殊欄位,並寫入所產生 LogEntry 的對應欄位。例如,若 JSON 含有 severity 屬性,系統會從 jsonPayload 將其移除,並改以記錄項目的 severity 形式顯示。

已知限制

將記錄從記錄檔接收器轉送至 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 使用日期篩選器和 RFC 3339 剖析
metadata.event_type 如果 has_principal、has_target、has_principal_user 為 true,則設為「USER_LOGIN」;如果 has_principal 和 has_target 為 true,則設為「NETWORK_CONNECTION」;如果 has_principal 為 false 且 has_target 為 true,則設為「USER_UNCATEGORIZED」;如果 has_principal 為 true,則設為「STATUS_UPDATE」;如果 has_principal_user 為 true,則設為「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_label 合併,其中包含鍵「appId」和欄位中的值
requestUser principal.user.email_addresses 如果符合電子郵件模式,則與 requestUser 合併
security_result security_result 從 security_result 合併
resource.labels.forwarding_rule_name security_result.rule_labels 與 rule_label 合併,其中包含鍵「forwarding_rule_name」和欄位中的值
嚴重性 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」
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.ip 從變更記錄對應
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.asset.ip 從變更記錄對應
protoPayload.authenticationInfo.principalEmail event.idm.read_only_udm.principal.user.email_addresses 從變更記錄對應
protoPayload.methodName event.idm.read_only_udm.metadata.product_event_type 從變更記錄對應
protoPayload.resourceName event.idm.read_only_udm.target.resource.name 從變更記錄對應
protoPayload.serviceName event.idm.read_only_udm.target.application 從變更記錄對應
protoPayload.resourceLocation.currentLocations event.idm.read_only_udm.target.resource.attribute.labels 從變更記錄對應
protoPayload.authenticationInfo.oauthInfo.oauthClientId event.idm.read_only_udm.principal.resource.attribute.labels 從變更記錄對應
protoPayload.requestMetadata.requestAttributes.time event.idm.read_only_udm.additional.fields 從變更記錄對應
operation.first event.idm.read_only_udm.additional.fields 從變更記錄對應
protoPayload.serviceData.updateService.request.updateMask event.idm.read_only_udm.additional.fields 從變更記錄對應
operation.id event.idm.read_only_udm.additional.fields 從變更記錄對應
protoPayload.authenticationInfo.serviceAccountKeyName event.idm.read_only_udm.additional.fields 從變更記錄對應
protoPayload.authorizationInfo.permission event.idm.read_only_udm.security_result.rule_name 從變更記錄對應
protoPayload.authorizationInfo.permissionType event.idm.read_only_udm.security_result.description 從變更記錄對應
protoPayload.authorizationInfo.granted event.idm.read_only_udm.security_result.action 從變更記錄對應
protoPayload.@type" , "labels.clone_id" and "operation.producer additional.labels 從變更記錄對應

變更記錄

查看這個剖析器的變更記錄

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