Raccogliere i log del proxy OAuth2

Supportato in:

Questo documento spiega come importare i log di OAuth2 Proxy in Google Security Operations utilizzando Google Cloud Storage V2.

OAuth2 Proxy è un reverse proxy CNCF Sandbox che fornisce l'autenticazione utilizzando provider OAuth2/OIDC (Google, GitHub, Keycloak, Azure AD e altri) per convalidare gli account per email, dominio o gruppo. Genera log di autenticazione (accesso riuscito/non riuscito), log delle richieste (richieste HTTP proxy con identità utente) e log delle applicazioni standard. Poiché OAuth2 Proxy viene eseguito come container in Kubernetes e scrive tutti i log in stdout, viene utilizzato un agente di raccolta di log nativo di Kubernetes (Fluentd) per inoltrare i log a un bucket GCS per l'importazione di Google SecOps.

Prima di iniziare

Assicurati di soddisfare i seguenti prerequisiti:

  • Un'istanza Google SecOps
  • Un progetto GCP con l'API Storage Cloud abilitata
  • Autorizzazioni per creare e gestire bucket GCS
  • Autorizzazioni per gestire le policy IAM nei bucket GCS
  • Un cluster Kubernetes in esecuzione con OAuth2 Proxy di cui è stato eseguito il deployment (tramite grafico Helm o deployment manuale)
  • kubectl accesso al cluster Kubernetes con autorizzazioni per creare DaemonSet, ConfigMap, Secret e spazi dei nomi
  • Una chiave JSON del account di servizio Google Cloud con autorizzazione storage.objects.create sul bucket GCS di destinazione

Crea un bucket Google Cloud Storage

  1. Vai alla console Google Cloud.
  2. Seleziona il tuo progetto o creane uno nuovo.
  3. Nel menu di navigazione, vai a Cloud Storage > Bucket.
  4. Fai clic su Crea bucket.
  5. Fornisci i seguenti dettagli di configurazione:

    Impostazione Valore
    Assegna un nome al bucket Inserisci un nome univoco globale (ad esempio oauth2-proxy-logs-bucket).
    Tipo di località Scegli in base alle tue esigenze (regione singola, a due regioni, multiregionale)
    Località Seleziona la posizione (ad esempio, us-central1).
    Classe di archiviazione Standard (consigliato per i log a cui si accede di frequente)
    Controllo dell'accesso Uniforme (consigliato)
    Strumenti di protezione (Facoltativo) Attiva il controllo delle versioni degli oggetti o la policy di conservazione
  6. Fai clic su Crea.

Configura la registrazione proxy OAuth2

OAuth2 Proxy scrive tre tipi di log in stdout: log standard, log di autenticazione e log delle richieste. Tutte e tre sono abilitate per impostazione predefinita. Per assicurarti che i log contengano il massimo livello di dettagli pertinenti alla sicurezza, configura OAuth2 Proxy con i seguenti flag di logging.

Opzione 1: configura tramite i valori del grafico Helm

  • Se OAuth2 Proxy viene implementato utilizzando il grafico Helm ufficiale, aggiungi quanto segue al file 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}}"
    
  • Applica i valori Helm aggiornati:

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

Opzione 2: configura tramite i flag della riga di comando

  • Se OAuth2 Proxy viene implementato utilizzando un manifest di deployment Kubernetes, aggiungi i seguenti argomenti alla specifica del container:

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

Opzione 3: configura tramite le variabili di ambiente

  • Imposta le seguenti variabili di ambiente nel container proxy OAuth2:

    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"
    

Verifica la registrazione di OAuth2 Proxy

  • Dopo aver applicato la configurazione, verifica che OAuth2 Proxy stia producendo log:

    kubectl logs -l app=oauth2-proxy -n <your-namespace> --tail=20
    
  • L'output include righe simili alle seguenti:

    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
    

Crea un account di servizio Google Cloud per Fluentd

Fluentd richiede un account di servizio Google Cloud con accesso in scrittura al bucket GCS.

  1. Nella console Google Cloud, vai a IAM e amministrazione > Service account.
  2. Fai clic su Crea account di servizio.
  3. Fornisci i seguenti dettagli di configurazione:
    • Nome del service account: inserisci fluentd-gcs-writer
    • Descrizione service account: inserisci Service account for Fluentd to write OAuth2 Proxy logs to GCS
  4. Fai clic su Crea e continua.
  5. Nella sezione Concedi a questo account di servizio l'accesso al progetto:
    1. Fai clic su Seleziona un ruolo.
    2. Cerca e seleziona Storage Object Admin.
  6. Fai clic su Continua.
  7. Fai clic su Fine.

Crea e scarica la chiave del account di servizio

  1. Nell'elenco Service account, fai clic sul account di servizio fluentd-gcs-writer.
  2. Vai alla scheda Chiavi.
  3. Fai clic su Aggiungi chiave > Crea nuova chiave.
  4. Seleziona JSON come tipo di chiave.
  5. Fai clic su Crea.
  6. Salva in modo sicuro il file della chiave JSON scaricato. Questo file viene utilizzato nel passaggio successivo.

Crea il secret Kubernetes per la chiave del account di servizio

  • Crea un secret Kubernetes contenente la chiave del account di servizio Google Cloud nello spazio dei nomi in cui verrà eseguito il deployment di Fluentd:

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

Esegui il deployment di Fluentd DaemonSet per raccogliere i log del proxy OAuth2

Esegui il deployment di Fluentd come DaemonSet nel cluster Kubernetes per raccogliere i log dei container dai pod proxy OAuth2 e inoltrarli al bucket GCS.

Crea ConfigMap Fluentd

  • Crea un file denominato fluentd-configmap.yaml con i seguenti contenuti:

    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>
    

Sostituisci i seguenti valori:

  • YOUR_GCP_PROJECT_ID: Il tuo ID progetto Google Cloud (ad esempio, my-project-123456)
  • oauth2-proxy-logs-bucket: il nome del bucket GCS creato in precedenza

  • Applica ConfigMap:

    kubectl apply -f fluentd-configmap.yaml
    

Crea Fluentd DaemonSet

  • Crea un file denominato fluentd-daemonset.yaml con i seguenti contenuti:

    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: {}
    
  • Applica il DaemonSet:

    kubectl apply -f fluentd-daemonset.yaml
    

Verifica il deployment di Fluentd

  1. Verifica che i pod Fluentd siano in esecuzione su ogni nodo:

    kubectl get pods -n logging -l k8s-app=fluentd-gcs
    
  2. Controlla i log di Fluentd per verificare che le scritture GCS siano state eseguite correttamente:

    kubectl logs -l k8s-app=fluentd-gcs -n logging --tail=20
    
  3. Verifica che i file di log vengano visualizzati nel bucket GCS:

    1. Vai a Cloud Storage > Bucket nella console di GCP.
    2. Fai clic sul bucket (ad esempio, oauth2-proxy-logs-bucket).
    3. Vai alla cartella oauth2-proxy-logs/.
    4. Verifica che i file .json siano presenti con timestamp recenti.

Recuperare il account di servizio Google SecOps

Google SecOps utilizza un account di servizio univoco per leggere i dati dal tuo bucket GCS. Devi concedere a questo account di servizio l'accesso al tuo bucket.

Recupera l'email del account di servizio

  1. Vai a Impostazioni SIEM > Feed.
  2. Fai clic su Aggiungi nuovo feed.
  3. Fai clic su Configura un singolo feed.
  4. Nel campo Nome feed, inserisci un nome per il feed (ad esempio, OAuth2 Proxy Logs).
  5. Seleziona Google Cloud Storage V2 come Tipo di origine.
  6. Seleziona Kubernetes Auth Proxy come Tipo di log.
  7. Fai clic su Ottieni service account. Verrà visualizzata un'email del account di servizio univoca, ad esempio:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. Copia questo indirizzo email per utilizzarlo nel passaggio successivo.

  9. Fai clic su Avanti.

  10. Specifica i valori per i seguenti parametri di input:

    • URL del bucket di archiviazione: inserisci l'URI del bucket GCS con il percorso del prefisso:

      gs://oauth2-proxy-logs-bucket/oauth2-proxy-logs/
      
    • Sostituisci oauth2-proxy-logs-bucket con il nome del tuo bucket GCS.

    • Opzione di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze:

      • Mai: non elimina mai i file dopo i trasferimenti (opzione consigliata per i test).
      • Elimina i file trasferiti: elimina i file dopo il trasferimento riuscito.
      • Elimina file trasferiti e directory vuote: elimina i file e le directory vuote dopo il trasferimento riuscito.

    • Età massima file: includi i file modificati nell'ultimo numero di giorni (il valore predefinito è 180 giorni)

    • Spazio dei nomi dell'asset: lo spazio dei nomi dell'asset

    • Etichette di importazione: l'etichetta da applicare agli eventi di questo feed

  11. Fai clic su Avanti.

  12. Controlla la nuova configurazione del feed nella schermata Finalizza e poi fai clic su Invia.

Concedi le autorizzazioni IAM al account di servizio Google SecOps

Il account di servizio Google SecOps deve avere il ruolo Visualizzatore oggetti Storage nel bucket GCS.

  1. Vai a Cloud Storage > Bucket.
  2. Fai clic sul nome del bucket (ad esempio oauth2-proxy-logs-bucket).
  3. Vai alla scheda Autorizzazioni.
  4. Fai clic su Concedi l'accesso.
  5. Fornisci i seguenti dettagli di configurazione:
    • Aggiungi entità: incolla l'email dell'account di servizio Google SecOps (ad esempio, chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com).
    • Assegna i ruoli: seleziona Visualizzatore oggetti Storage
  6. Fai clic su Salva.

Riferimento ai log del proxy OAuth2

La tabella seguente descrive i campi di log generati da OAuth2 Proxy e la loro rilevanza per la sicurezza:

Campi dei log di autenticazione

Campo Esempio Descrizione
Client 10.0.0.1 Indirizzo IP client/remoto (utilizza l'intestazione X-Real-IP se --reverse-proxy=true)
RequestID 00010203-0405-4607-8809-0a0b0c0d0e0f ID richiesta dall'intestazione X-Request-Id (UUID casuale se vuoto)
Nome utente user@example.com Email o nome utente della richiesta di autenticazione
Timestamp 2024/01/15 10:30:00 Data e ora dell'evento di autenticazione
Stato AuthSuccess Risultato dell'autenticazione: AuthSuccess, AuthFailure o AuthError
Messaggio Authenticated via OAuth2 Dettagli del tentativo di autenticazione

Campi dei log delle richieste

Campo Esempio Descrizione
Client 10.0.0.1 Indirizzo IP client/remoto
RequestID 00010203-0405-4607-8809-0a0b0c0d0e0f ID richiesta
Nome utente user@example.com Email dell'utente autenticato
Timestamp 2024/01/15 10:30:01 Data e ora della richiesta
Host app.example.com Valore dell'intestazione Host
RequestMethod GET Metodo di richiesta HTTP
Upstream 10.0.0.5:8080 Server upstream che ha gestito la richiesta
RequestURI /dashboard Percorso URI della richiesta
Protocollo HTTP/1.1 Protocollo richiesta
UserAgent Mozilla/5.0 Stringa completa dello user agent
StatusCode 200 Codice di stato risposta HTTP
ResponseSize 1234 Dimensioni della risposta in byte
RequestDuration 0.005 Tempo di elaborazione della richiesta in secondi

Tabella di mappatura UDM

Campo log Mappatura UDM Logica
about about Informazioni sull'evento
http_req_id_field additional.fields Campi aggiuntivi non coperti dallo schema UDM standard
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 Descrizione dell'evento
event_type metadata.event_type Tipo di evento
labels.request_id metadata.product_log_id Identificatore log specifico del prodotto
insertId metadata.product_log_id
jsonPayload.chartVersion metadata.product_version Versione del prodotto
httpRequest.protocol network.application_protocol Protocollo applicativo utilizzato nella connessione di rete
network.direction network.direction Direzione del traffico di rete
httpRequest.requestMethod network.http.method Metodo HTTP
http_method network.http.method
httpRequest.status network.http.response_code Codice di risposta HTTP
httpRequest.userAgent network.http.user_agent User agent HTTP
requestMetadata.callerSuppliedUserAgent network.http.user_agent
labels.protocol network.ip_protocol Protocollo IP
httpRequest.responseSize network.received_bytes Numero di byte ricevuti
labels.total_received_bytes network.received_bytes
httpRequest.requestSize network.sent_bytes Numero di byte inviati
labels.total_sent_bytes network.sent_bytes
jsonPayload.session network.session_id Identificatore sessione
labels.service_authentication_policy network.tls.cipher Suite di crittografia TLS
entità entità Entità principale coinvolta nell'evento
principal_hostname principal.hostname Nome host dell'entità
prin_userid principal.user.userid ID utente dell'entità
security_result security_result Risultato della valutazione della sicurezza
target target Entità target coinvolta nell'evento
target_hostname target.hostname Nome host della destinazione
resource_sub_type target.resource.resource_subtype Sottotipo della risorsa di destinazione
target_userid target.user.userid ID utente della destinazione
metadata.product_name metadata.product_name Nome del prodotto
metadata.vendor_name metadata.vendor_name Nome fornitore

Log delle modifiche

Visualizza il log delle modifiche per questo parser

Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.