收集 OAuth2 Proxy 記錄

支援的國家/地區:

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

OAuth2 Proxy 是 CNCF Sandbox 反向 Proxy,可使用 OAuth2/OIDC 提供者 (Google、GitHub、Keycloak、Azure AD 等) 進行驗證,並依據電子郵件、網域或群組驗證帳戶。這項服務會產生驗證記錄 (登入成功/失敗)、要求記錄 (含使用者身分識別的代理 HTTP 要求) 和標準應用程式記錄。由於 OAuth2 Proxy 會在 Kubernetes 中以容器形式執行,並將所有記錄寫入 stdout,因此系統會使用 Kubernetes 原生記錄收集器 (Fluentd),將記錄轉送至 GCS 儲存空間,供 Google SecOps 擷取。

事前準備

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

  • Google SecOps 執行個體
  • 已啟用 Cloud Storage API 的 GCP 專案
  • 建立及管理 GCS bucket 的權限
  • 管理 Google Cloud Storage 值區 IAM 政策的權限
  • 已部署 OAuth2 Proxy 的 Kubernetes 叢集 (透過 Helm 資訊套件或手動部署)
  • kubectl 存取 Kubernetes 叢集,並具備建立 DaemonSet、ConfigMap、密鑰和命名空間的權限
  • 具有目標 GCS bucket storage.objects.create 權限的 GCP 服務帳戶 JSON 金鑰

建立 Google Cloud Storage bucket

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

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

設定 OAuth2 Proxy 記錄

OAuth2 Proxy 會將三種類型的記錄寫入 stdout:標準記錄、驗證記錄和要求記錄。這三項功能預設為啟用。為確保記錄包含與安全性相關的詳細資料,請使用下列記錄旗標設定 OAuth2 Proxy。

方法 1:透過 Helm 資訊套件值設定

  • 如果 OAuth2 Proxy 是使用官方 Helm Chart 部署,請將下列內容新增至 values.yaml 檔案:

    config:
      configFile: |-
        standard_logging = true
        auth_logging = true
        request_logging = true
        silence_ping_logging = true
            standard_logging_format = "[{{.Timestamp}}] [{{.File}}] {{.Message}}"
        auth_logging_format = "{{.Client}} - {{.RequestID}} - {{.Username}} [{{.Timestamp}}] [{{.Status}}] {{.Message}}"
        request_logging_format = "{{.Client}} - {{.RequestID}} - {{.Username}} [{{.Timestamp}}] {{.Host}} {{.RequestMethod}} {{.Upstream}} {{.RequestURI}} {{.Protocol}} {{.UserAgent}} {{.StatusCode}} {{.ResponseSize}} {{.RequestDuration}}"
    
  • 套用更新的 Helm 值:

    helm upgrade oauth2-proxy oauth2-proxy/oauth2-proxy -f values.yaml -n <your-namespace>
    

方法 2:透過指令列旗標設定

  • 如果 OAuth2 Proxy 是使用 Kubernetes Deployment 資訊清單部署,請將下列引數新增至容器規格:

    args:
      - --standard-logging=true
      - --auth-logging=true
      - --request-logging=true
      - --silence-ping-logging=true
    

選項 3:透過環境變數設定

  • 在 OAuth2 Proxy 容器中設定下列環境變數:

    env:
      - name: OAUTH2_PROXY_STANDARD_LOGGING
        value: "true"
      - name: OAUTH2_PROXY_AUTH_LOGGING
        value: "true"
      - name: OAUTH2_PROXY_REQUEST_LOGGING
        value: "true"
      - name: OAUTH2_PROXY_SILENCE_PING_LOGGING
        value: "true"
    

驗證 OAuth2 Proxy 記錄

  • 套用設定後,請確認 OAuth2 Proxy 是否產生記錄:

    kubectl logs -l app=oauth2-proxy -n <your-namespace> --tail=20
    
  • 輸出內容會包含類似下列內容的行:

    10.0.0.1 - abc123 - user@example.com [2024/01/15 10:30:00] [AuthSuccess] Authenticated via OAuth2
    10.0.0.1 - abc123 - user@example.com [2024/01/15 10:30:01] example.com GET 10.0.0.5:8080 "/dashboard" HTTP/1.1 "Mozilla/5.0" 200 1234 0.005
    

為 Fluentd 建立 GCP 服務帳戶

Fluentd 需要具備 GCS bucket 寫入權限的 GCP 服務帳戶。

  1. GCP 控制台中,依序前往「IAM & Admin」(IAM 與管理) >「Service Accounts」(服務帳戶)
  2. 按一下「Create Service Account」(建立服務帳戶)
  3. 請提供下列設定詳細資料:
    • 服務帳戶名稱:輸入 fluentd-gcs-writer
    • 服務帳戶說明:輸入 Service account for Fluentd to write OAuth2 Proxy logs to GCS
  4. 按一下「建立並繼續」
  5. 在「將專案存取權授予這個服務帳戶」部分:
    1. 按一下「選擇角色」
    2. 搜尋並選取「Storage 物件管理員」
  6. 按一下「繼續」
  7. 按一下 [完成]

建立及下載服務帳戶金鑰

  1. 在「Service Accounts」(服務帳戶) 清單中,按一下 fluentd-gcs-writer 服務帳戶。
  2. 前往「金鑰」分頁標籤。
  3. 依序點選「新增金鑰」>「建立新的金鑰」
  4. 選取「JSON」做為金鑰類型。
  5. 點選「建立」
  6. 請妥善儲存下載的 JSON 金鑰檔案。這個檔案會在下一個步驟中使用。

為服務帳戶金鑰建立 Kubernetes Secret

  • 在要部署 Fluentd 的命名空間中,建立包含 GCP 服務帳戶金鑰的 Kubernetes 密鑰:

    kubectl create namespace logging
    kubectl create secret generic fluentd-gcs-key \
      --from-file=service-account-key.json=<path-to-downloaded-key>.json \
      -n logging
    

部署 Fluentd DaemonSet,收集 OAuth2 Proxy 記錄

在 Kubernetes 叢集中將 Fluentd 部署為 DaemonSet,從 OAuth2 Proxy Pod 收集容器記錄,並轉送至 GCS bucket。

建立 Fluentd ConfigMap

  • 建立名為 fluentd-configmap.yaml 的檔案,並加入以下內容:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: fluentd-gcs-config
      namespace: logging
    data:
      fluent.conf: |
        <source>
          @type tail
          read_from_head true
          tag kubernetes.*
          path /var/log/containers/*oauth2-proxy*.log
          pos_file /var/log/fluentd-oauth2-proxy.log.pos
          <parse>
            @type regexp
            expression /^(?<time>[^ ]+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
            time_format %Y-%m-%dT%H:%M:%S.%N%z
          </parse>
        </source>
    
        <filter kubernetes.**>
          @type kubernetes_metadata
          @id filter_kube_metadata
        </filter>
    
        <match kubernetes.**>
          @type gcs
          project YOUR_GCP_PROJECT_ID
          keyfile /etc/secrets/service-account-key.json
          bucket oauth2-proxy-logs-bucket
          path oauth2-proxy-logs/%Y/%m/%d/
          object_key_format %{path}%{time_slice}_%{hostname}_%{index}.%{file_extension}
          <buffer tag,time>
            @type file
            path /var/log/fluentd/gcs
            timekey 300
            timekey_wait 60
            timekey_use_utc true
            chunk_limit_size 10MB
          </buffer>
          <format>
            @type json
          </format>
        </match>
    

替換下列值:

  • YOUR_GCP_PROJECT_ID:您的 GCP 專案 ID (例如 my-project-123456)
  • oauth2-proxy-logs-bucket:先前建立的 GCS bucket 名稱

  • 套用 ConfigMap:

    kubectl apply -f fluentd-configmap.yaml
    

建立 Fluentd DaemonSet

  • 建立名為 fluentd-daemonset.yaml 的檔案,並加入以下內容:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: fluentd-gcs
      namespace: logging
      labels:
        k8s-app: fluentd-gcs
    spec:
      selector:
        matchLabels:
          k8s-app: fluentd-gcs
      template:
        metadata:
          labels:
            k8s-app: fluentd-gcs
        spec:
          tolerations:
            - key: node-role.kubernetes.io/control-plane
              effect: NoSchedule
            - key: node-role.kubernetes.io/master
              effect: NoSchedule
          containers:
            - name: fluentd-gcs
              image: fluent/fluentd-kubernetes-daemonset:v1-debian-gcs
              resources:
                limits:
                  memory: 512Mi
                requests:
                  cpu: 100m
                  memory: 200Mi
              volumeMounts:
                - name: fluentd-gcs-config-volume
                  mountPath: /fluentd/etc/fluent.conf
                  subPath: fluent.conf
                  readOnly: true
                - name: fluentd-gcs-secrets-volume
                  mountPath: /etc/secrets/service-account-key.json
                  subPath: service-account-key.json
                  readOnly: true
                - name: varlog
                  mountPath: /var/log
                - name: dockercontainerlogdirectory
                  mountPath: /var/log/pods
                  readOnly: true
                - name: fluentd-buffer
                  mountPath: /var/log/fluentd
          terminationGracePeriodSeconds: 30
          volumes:
            - name: fluentd-gcs-config-volume
              configMap:
                name: fluentd-gcs-config
            - name: fluentd-gcs-secrets-volume
              secret:
                secretName: fluentd-gcs-key
            - name: varlog
              hostPath:
                path: /var/log
            - name: dockercontainerlogdirectory
              hostPath:
                path: /var/log/pods
            - name: fluentd-buffer
              emptyDir: {}
    
  • 套用 DaemonSet:

    kubectl apply -f fluentd-daemonset.yaml
    

驗證 Fluentd 部署作業

  1. 確認每個節點上都正在執行 Fluentd Pod:

    kubectl get pods -n logging -l k8s-app=fluentd-gcs
    
  2. 檢查 Fluentd 記錄,確認是否成功寫入 GCS:

    kubectl logs -l k8s-app=fluentd-gcs -n logging --tail=20
    
  3. 確認記錄檔顯示在 GCS bucket 中:

    1. 前往 GCP Console 的「Cloud Storage」>「Buckets」頁面。
    2. 點選 bucket (例如 oauth2-proxy-logs-bucket)。
    3. 前往 oauth2-proxy-logs/ 資料夾。
    4. 確認是否有時間戳記為最近的 .json 檔案。

擷取 Google SecOps 服務帳戶

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

取得服務帳戶電子郵件地址

  1. 依序前往「SIEM 設定」>「動態饋給」
  2. 按一下「新增動態消息」
  3. 按一下「設定單一動態饋給」
  4. 在「動態饋給名稱」欄位中輸入動態饋給名稱 (例如 OAuth2 Proxy Logs)。
  5. 選取「Google Cloud Storage V2」做為「來源類型」
  6. 選取「Kubernetes Auth Proxy」做為「記錄類型」
  7. 按一下「取得服務帳戶」,系統會顯示專屬服務帳戶電子郵件地址,例如:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. 複製這個電子郵件地址,以便在下一步中使用。

  9. 點選「下一步」

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

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

      gs://oauth2-proxy-logs-bucket/oauth2-proxy-logs/
      
    • 請將 oauth2-proxy-logs-bucket 替換為您的 GCS bucket 名稱。

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

      • 永不:移轉後一律不刪除任何檔案 (建議用於測試)。
      • 刪除已轉移的檔案:成功轉移檔案後刪除檔案。
      • 刪除已轉移的檔案和空白目錄:成功轉移後刪除檔案和空白目錄。

    • 檔案存在時間上限:包含在過去天數內修改的檔案 (預設為 180 天)

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

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

  11. 點選「下一步」

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

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

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

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

OAuth2 Proxy 記錄參考資料

下表說明 OAuth2 Proxy 產生的記錄檔欄位,以及這些欄位與安全性的關聯:

驗證記錄欄位

欄位 範例 說明
客戶 10.0.0.1 用戶端/遠端 IP 位址 (使用 X-Real-IP 標頭,如果 --reverse-proxy=true)
RequestID 00010203-0405-4607-8809-0a0b0c0d0e0f X-Request-Id 標頭中的要求 ID (如果為空白,則為隨機 UUID)
使用者名稱 user@example.com 驗證要求的電子郵件地址或使用者名稱
時間戳記 2024/01/15 10:30:00 驗證事件的日期和時間
狀態 AuthSuccess 驗證結果:AuthSuccessAuthFailureAuthError
訊息 Authenticated via OAuth2 驗證嘗試的詳細資料

要求記錄欄位

欄位 範例 說明
客戶 10.0.0.1 用戶端/遠端 IP 位址
RequestID 00010203-0405-4607-8809-0a0b0c0d0e0f 要求 ID
使用者名稱 user@example.com 通過驗證的使用者電子郵件地址
時間戳記 2024/01/15 10:30:01 要求日期和時間
主機 app.example.com Host 標頭的值
RequestMethod GET HTTP 要求方法
向上 10.0.0.5:8080 處理要求的上游伺服器
RequestURI /dashboard 要求的 URI 路徑
通訊協定 HTTP/1.1 要求通訊協定
UserAgent Mozilla/5.0 完整的使用者代理程式字串
StatusCode 200 HTTP 回應狀態碼
ResponseSize 1234 回應大小 (以位元組為單位)
RequestDuration 0.005 要求處理時間 (以秒為單位)

UDM 對應表

記錄欄位 UDM 對應 邏輯
關於 關於 活動資訊
http_req_id_field additional.fields 標準 UDM 結構定義未涵蓋的其他欄位
http_req_path_field additional.fields
k8s_pod_app_field additional.fields
k8s_pod_template_hash_field additional.fields
k8s_pod_tls_mode_field additional.fields
k8s_pod_canonical_revision_field additional.fields
k8s_pod_canonical_name_field additional.fields
pod_name additional.fields
cntnr_name additional.fields
destination_canonical_revision additional.fields
requested_server additional.fields
nodename_label additional.fields
componentName_label additional.fields
componentVersion_label additional.fields
azureResourceID_label additional.fields
producer_label additional.fields
first_label additional.fields
last_label additional.fields
meta_name additional.fields
resource_version_label additional.fields
request_apiVersion additional.fields
request_kind_label additional.fields
request_type_label additional.fields
response_apiVersion additional.fields
response_kind_label additional.fields
response_type_label additional.fields
jsonPayload.message metadata.description 事件說明
event_type metadata.event_type 活動類型
labels.request_id metadata.product_log_id 產品專屬記錄 ID
insertId metadata.product_log_id
jsonPayload.chartVersion metadata.product_version 產品版本
httpRequest.protocol network.application_protocol 網路連線中使用的應用程式通訊協定
network.direction network.direction 網路流量方向
httpRequest.requestMethod network.http.method HTTP 方法
http_method network.http.method
httpRequest.status network.http.response_code HTTP 回應代碼
httpRequest.userAgent network.http.user_agent HTTP 使用者代理程式
requestMetadata.callerSuppliedUserAgent network.http.user_agent
labels.protocol network.ip_protocol IP 通訊協定
httpRequest.responseSize network.received_bytes 收到的位元組數
labels.total_received_bytes network.received_bytes
httpRequest.requestSize network.sent_bytes 傳送的位元組數
labels.total_sent_bytes network.sent_bytes
jsonPayload.session network.session_id 工作階段 ID
labels.service_authentication_policy network.tls.cipher 傳輸層安全標準 (TLS) 加密套件
主體 主體 活動涉及的主要實體
principal_hostname principal.hostname 主體的主機名稱
prin_userid principal.user.userid 主體的使用者 ID
security_result security_result 安全評估結果
目標 目標 活動中涉及的目標實體
target_hostname target.hostname 目標的主機名稱
resource_sub_type target.resource.resource_subtype 目標資源的子類型
target_userid target.user.userid 目標的使用者 ID
metadata.product_name metadata.product_name 產品名稱
metadata.vendor_name metadata.vendor_name 供應商名稱

變更記錄

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

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