Mengumpulkan log Proxy OAuth2

Didukung di:

Dokumen ini menjelaskan cara menyerap log OAuth2 Proxy ke Google Security Operations menggunakan Google Cloud Storage V2.

OAuth2 Proxy adalah reverse proxy CNCF Sandbox yang menyediakan autentikasi menggunakan penyedia OAuth2/OIDC (Google, GitHub, Keycloak, Azure AD, dan lainnya) untuk memvalidasi akun berdasarkan email, domain, atau grup. Layanan ini menghasilkan log autentikasi (keberhasilan/kegagalan login), log permintaan (permintaan HTTP yang di-proxy dengan identitas pengguna), dan log aplikasi standar. Karena OAuth2 Proxy berjalan sebagai container di Kubernetes dan menulis semua log ke stdout, pengumpul log native Kubernetes (Fluentd) digunakan untuk meneruskan log ke bucket GCS untuk penyerapan Google SecOps.

Sebelum memulai

Pastikan Anda memiliki prasyarat berikut:

  • Instance Google SecOps
  • Project GCP dengan Cloud Storage API diaktifkan
  • Izin untuk membuat dan mengelola bucket GCS
  • Izin untuk mengelola kebijakan IAM di bucket GCS
  • Cluster Kubernetes yang sedang berjalan dengan OAuth2 Proxy yang di-deploy (melalui diagram Helm atau deployment manual)
  • Akses kubectl ke cluster Kubernetes dengan izin untuk membuat DaemonSet, ConfigMap, Secret, dan Namespace
  • Kunci JSON akun layanan GCP dengan izin storage.objects.create di bucket GCS target

Membuat bucket Google Cloud Storage

  1. Buka Konsol Google Cloud.
  2. Pilih project Anda atau buat project baru.
  3. Di menu navigasi, buka Cloud Storage > Buckets.
  4. Klik Create bucket.
  5. Berikan detail konfigurasi berikut:

    Setelan Nilai
    Beri nama bucket Anda Masukkan nama yang unik secara global (misalnya, oauth2-proxy-logs-bucket)
    Location type Pilih berdasarkan kebutuhan Anda (Region, Dual-region, Multi-region)
    Location Pilih lokasi (misalnya, us-central1)
    Kelas penyimpanan Standar (direkomendasikan untuk log yang sering diakses)
    Access control Seragam (direkomendasikan)
    Alat perlindungan Opsional: Aktifkan pembuatan versi objek atau kebijakan retensi
  6. Klik Create.

Mengonfigurasi logging Proxy OAuth2

OAuth2 Proxy menulis tiga jenis log ke stdout: log standar, log autentikasi, dan log permintaan. Ketiganya diaktifkan secara default. Untuk memastikan log berisi detail yang relevan dengan keamanan secara maksimal, konfigurasi OAuth2 Proxy dengan tanda logging berikut.

Opsi 1: Mengonfigurasi melalui nilai diagram Helm

  • Jika OAuth2 Proxy di-deploy menggunakan Helm chart resmi, tambahkan kode berikut ke file values.yaml Anda:

    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}}"
    
  • Terapkan nilai Helm yang diperbarui:

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

Opsi 2: Mengonfigurasi melalui tanda command line

  • Jika OAuth2 Proxy di-deploy menggunakan manifes Deployment Kubernetes, tambahkan argumen berikut ke spesifikasi container:

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

Opsi 3: Mengonfigurasi melalui variabel lingkungan

  • Tetapkan variabel lingkungan berikut di container 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"
    

Memverifikasi logging Proxy OAuth2

  • Setelah menerapkan konfigurasi, verifikasi bahwa OAuth2 Proxy menghasilkan log:

    kubectl logs -l app=oauth2-proxy -n <your-namespace> --tail=20
    
  • Output-nya mencakup baris yang mirip dengan berikut ini:

    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
    

Buat akun layanan GCP untuk Fluentd

Fluentd memerlukan akun layanan GCP dengan akses tulis ke bucket GCS.

  1. Di GCP Console, buka IAM & Admin > Service Accounts.
  2. Klik Create Service Account.
  3. Berikan detail konfigurasi berikut:
    • Nama akun layanan: Masukkan fluentd-gcs-writer
    • Deskripsi akun layanan: Masukkan Service account for Fluentd to write OAuth2 Proxy logs to GCS
  4. Klik Create and Continue.
  5. Di bagian Berikan akun layanan ini akses ke project:
    1. Klik Pilih peran.
    2. Telusuri dan pilih Storage Object Admin.
  6. Klik Lanjutkan.
  7. Klik Done.

Membuat dan mendownload kunci akun layanan

  1. Di daftar Service Accounts, klik akun layanan fluentd-gcs-writer.
  2. Buka tab Kunci.
  3. Klik Tambahkan Kunci > Buat kunci baru.
  4. Pilih JSON sebagai jenis kunci.
  5. Klik Create.
  6. Simpan file kunci JSON yang didownload dengan aman. File ini akan digunakan pada langkah berikutnya.

Buat secret Kubernetes untuk kunci akun layanan

  • Buat secret Kubernetes yang berisi kunci akun layanan GCP di namespace tempat Fluentd akan di-deploy:

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

Men-deploy DaemonSet Fluentd untuk mengumpulkan log Proxy OAuth2

Deploy Fluentd sebagai DaemonSet di cluster Kubernetes untuk mengumpulkan log container dari pod OAuth2 Proxy dan meneruskannya ke bucket GCS.

Buat ConfigMap Fluentd

  • Buat file bernama fluentd-configmap.yaml dengan konten berikut:

    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>
    

Ganti nilai berikut:

  • YOUR_GCP_PROJECT_ID: Project ID GCP Anda (misalnya, my-project-123456)
  • oauth2-proxy-logs-bucket: Nama bucket GCS yang dibuat sebelumnya

  • Terapkan ConfigMap:

    kubectl apply -f fluentd-configmap.yaml
    

Buat DaemonSet Fluentd

  • Buat file bernama fluentd-daemonset.yaml dengan konten berikut:

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

    kubectl apply -f fluentd-daemonset.yaml
    

Memverifikasi deployment Fluentd

  1. Pastikan pod Fluentd berjalan di setiap node:

    kubectl get pods -n logging -l k8s-app=fluentd-gcs
    
  2. Periksa log Fluentd untuk penulisan GCS yang berhasil:

    kubectl logs -l k8s-app=fluentd-gcs -n logging --tail=20
    
  3. Pastikan file log muncul di bucket GCS:

    1. Buka Cloud Storage > Buckets di GCP Console.
    2. Klik bucket (misalnya, oauth2-proxy-logs-bucket).
    3. Buka folder oauth2-proxy-logs/.
    4. Pastikan file .json ada dengan stempel waktu terbaru.

Mengambil akun layanan Google SecOps

Google SecOps menggunakan akun layanan unik untuk membaca data dari bucket GCS Anda. Anda harus memberi akun layanan ini akses ke bucket Anda.

Dapatkan email akun layanan

  1. Buka Setelan SIEM > Feed.
  2. Klik Tambahkan Feed Baru.
  3. Klik Konfigurasi satu feed.
  4. Di kolom Nama feed, masukkan nama untuk feed (misalnya, OAuth2 Proxy Logs).
  5. Pilih Google Cloud Storage V2 sebagai Source type.
  6. Pilih Kubernetes Auth Proxy sebagai Jenis log.
  7. Klik Get Service Account. Email akun layanan yang unik akan ditampilkan, misalnya:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. Salin alamat email ini untuk digunakan di langkah berikutnya.

  9. Klik Berikutnya.

  10. Tentukan nilai untuk parameter input berikut:

    • URL bucket penyimpanan: Masukkan URI bucket GCS dengan jalur awalan:

      gs://oauth2-proxy-logs-bucket/oauth2-proxy-logs/
      
    • Ganti oauth2-proxy-logs-bucket dengan nama bucket GCS Anda.

    • Opsi penghapusan sumber: Pilih opsi penghapusan sesuai preferensi Anda:

      • Jangan pernah: Tidak pernah menghapus file apa pun setelah transfer (direkomendasikan untuk pengujian).
      • Hapus file yang ditransfer: Menghapus file setelah transfer berhasil.
      • Hapus file yang ditransfer dan direktori kosong: Menghapus file dan direktori kosong setelah transfer berhasil.

    • Usia File Maksimum: Menyertakan file yang diubah dalam beberapa hari terakhir (defaultnya adalah 180 hari)

    • Namespace aset: Namespace aset

    • Label penyerapan: Label yang akan diterapkan ke peristiwa dari feed ini

  11. Klik Berikutnya.

  12. Tinjau konfigurasi feed baru Anda di layar Selesaikan, lalu klik Kirim.

Memberikan izin IAM ke akun layanan Google SecOps

Akun layanan Google SecOps memerlukan peran Storage Object Viewer di bucket GCS Anda.

  1. Buka Cloud Storage > Buckets.
  2. Klik nama bucket Anda (misalnya, oauth2-proxy-logs-bucket).
  3. Buka tab Izin.
  4. Klik Grant access.
  5. Berikan detail konfigurasi berikut:
    • Add principals: Tempel email akun layanan Google SecOps (misalnya, chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com)
    • Tetapkan peran: Pilih Storage Object Viewer
  6. Klik Simpan.

Referensi log OAuth2 Proxy

Tabel berikut menjelaskan kolom log yang dihasilkan oleh OAuth2 Proxy dan relevansi keamanannya:

Kolom log autentikasi

Kolom Contoh Deskripsi
Klien 10.0.0.1 Alamat IP klien/jarak jauh (menggunakan header X-Real-IP jika --reverse-proxy=true)
RequestID 00010203-0405-4607-8809-0a0b0c0d0e0f ID permintaan dari header X-Request-Id (UUID acak jika kosong)
Nama pengguna user@example.com Email atau nama pengguna permintaan autentikasi
Stempel waktu 2024/01/15 10:30:00 Tanggal dan waktu peristiwa autentikasi
Status AuthSuccess Hasil autentikasi: AuthSuccess, AuthFailure, atau AuthError
Pesan Authenticated via OAuth2 Detail upaya autentikasi

Kolom log permintaan

Kolom Contoh Deskripsi
Klien 10.0.0.1 Alamat IP klien/jarak jauh
RequestID 00010203-0405-4607-8809-0a0b0c0d0e0f ID Permintaan
Nama pengguna user@example.com Email pengguna yang diautentikasi
Stempel waktu 2024/01/15 10:30:01 Tanggal dan waktu permintaan
Host app.example.com Nilai header Host
RequestMethod GET Metode permintaan HTTP
Upstream 10.0.0.5:8080 Server upstream yang menangani permintaan
RequestURI /dashboard Jalur URI permintaan
Protokol HTTP/1.1 Protokol permintaan
UserAgent Mozilla/5.0 String agen pengguna lengkap
StatusCode 200 Kode status respons HTTP
ResponseSize 1234 Ukuran respons dalam byte
RequestDuration 0.005 Waktu pemrosesan permintaan dalam detik

Tabel pemetaan UDM

Kolom Log Pemetaan UDM Logika
tentang tentang Informasi tentang acara
http_req_id_field additional.fields Kolom tambahan yang tidak tercakup dalam skema UDM standar
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 Deskripsi peristiwa
event_type metadata.event_type Jenis acara
labels.request_id metadata.product_log_id ID log khusus produk
insertId metadata.product_log_id
jsonPayload.chartVersion metadata.product_version Versi produk
httpRequest.protocol network.application_protocol Protokol aplikasi yang digunakan dalam koneksi jaringan
network.direction network.direction Arah traffic jaringan
httpRequest.requestMethod network.http.method Metode HTTP
http_method network.http.method
httpRequest.status network.http.response_code Kode respons HTTP
httpRequest.userAgent network.http.user_agent Agen pengguna HTTP
requestMetadata.callerSuppliedUserAgent network.http.user_agent
labels.protocol network.ip_protocol Protokol IP
httpRequest.responseSize network.received_bytes Jumlah byte yang diterima
labels.total_received_bytes network.received_bytes
httpRequest.requestSize network.sent_bytes Jumlah byte yang dikirim
labels.total_sent_bytes network.sent_bytes
jsonPayload.session network.session_id ID sesi
labels.service_authentication_policy network.tls.cipher Cipher suite TLS
utama utama Entitas utama yang terlibat dalam peristiwa
principal_hostname principal.hostname Nama host utama
prin_userid principal.user.userid ID pengguna prinsipal
security_result security_result Hasil evaluasi keamanan
target target Entitas target yang terlibat dalam acara
target_hostname target.hostname Nama host target
resource_sub_type target.resource.resource_subtype Subjenis resource target
target_userid target.user.userid ID pengguna target
metadata.product_name metadata.product_name Nama produk
metadata.vendor_name metadata.vendor_name Nama vendor

Log Perubahan

Melihat Log Perubahan untuk parser ini

Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.