Mengumpulkan log audit Slack
Dokumen ini menjelaskan cara menyerap Log Audit Slack ke Google Security Operations menggunakan fungsi Google Cloud Run. Parser menangani dua format log audit Slack. Pertama-tama, fungsi ini menormalisasi nilai boolean dan menghapus kolom yang telah ditentukan sebelumnya. Kemudian, kolom "message" diuraikan sebagai JSON, dan pesan non-JSON akan diabaikan. Bergantung pada keberadaan kolom tertentu (date_create
dan user_id
), parser menerapkan logika yang berbeda untuk memetakan kolom log mentah ke UDM, termasuk metadata, principal, jaringan, target, dan informasi tentang, serta membuat hasil keamanan.
Sebelum memulai
Pastikan Anda memenuhi prasyarat berikut:
- Instance Google SecOps
- Akses istimewa ke tenant Slack Enterprise Grid dan Konsol Admin
- Akses istimewa ke fungsi Cloud Run dan Cloud Scheduler GCP
Prasyarat pengumpulan Log Audit Slack (ID Aplikasi, Token OAuth, ID Organisasi)
- Login ke Konsol Admin Slack untuk organisasi Enterprise Grid Anda.
- Buka https://api.slack.com/apps, lalu klik Create New App > From scratch.
- Masukkan Nama Aplikasi dan pilih Ruang Kerja Slack Pengembangan Anda.
- Klik Create App.
- Buka OAuth & Izin di sidebar kiri.
- Buka bagian Cakupan dan tambahkan Cakupan Token Pengguna berikut:
- auditlogs:read
- Klik Instal ke Workspace > Izinkan.
- Setelah diinstal, buka Aplikasi Tingkat Org. > Instal ke Organisasi.
- Beri otorisasi aplikasi dengan akun Pemilik/Admin Organisasi.
- Salin dan simpan Token OAuth Pengguna yang dimulai dengan
xoxp-
(ini adalah SLACK_ADMIN_TOKEN Anda). - Salin ID Organisasi Anda yang dapat ditemukan di Konsol Admin Slack di bagian Setelan & Izin > Setelan organisasi.
Menyiapkan direktori
- Buat direktori baru di komputer lokal Anda untuk deployment fungsi Cloud Run.
- Download file berikut dari repositori GitHub ingestion-scripts Chronicle:
- Dari folder slack, download:
.env.yml
main.py
requirements.txt
- Dari root repositori, download seluruh direktori common dengan semua filenya:
common/__init__.py
common/auth.py
common/env_constants.py
common/ingest.py
common/status.py
common/utils.py
- Dari folder slack, download:
- Tempatkan semua file yang didownload ke direktori deployment Anda.
Struktur direktori Anda akan terlihat seperti ini:
deployment_directory/
├─common/
│ ├─__init__.py
│ ├─auth.py
│ ├─env_constants.py
│ ├─ingest.py
│ ├─status.py
│ └─utils.py
├─.env.yml
├─main.py
└─requirements.txt
Membuat secret di Google Secret Manager
- Di Google Cloud console, buka Security > Secret Manager.
- Klik Buat Secret.
- Berikan detail konfigurasi berikut untuk akun layanan Chronicle:
- Nama: Masukkan
chronicle-service-account
. - Nilai rahasia: Tempelkan konten file JSON autentikasi penyerapan Google SecOps Anda.
- Nama: Masukkan
- Klik Create secret.
Salin nama resource secret dalam format berikut:
projects/<PROJECT_ID>/secrets/chronicle-service-account/versions/latest
Klik Create Secret lagi untuk membuat secret kedua.
Berikan detail konfigurasi berikut untuk token Slack:
- Nama: Masukkan
slack-admin-token
. - Nilai rahasia: Tempelkan Token OAuth Pengguna Slack Anda (dimulai dengan
xoxp-
).
- Nama: Masukkan
Klik Create secret.
Salin nama resource secret dalam format berikut:
projects/<PROJECT_ID>/secrets/slack-admin-token/versions/latest
Menetapkan variabel lingkungan runtime yang diperlukan
- Buka file
.env.yml
di direktori deployment Anda. Konfigurasi variabel lingkungan dengan nilai Anda:
CHRONICLE_CUSTOMER_ID: "<your-chronicle-customer-id>" CHRONICLE_REGION: us CHRONICLE_SERVICE_ACCOUNT: "projects/<PROJECT_ID>/secrets/chronicle-service-account/versions/latest" CHRONICLE_NAMESPACE: "" POLL_INTERVAL: "5" SLACK_ADMIN_TOKEN: "projects/<PROJECT_ID>/secrets/slack-admin-token/versions/latest"
- Ganti kode berikut:
<your-chronicle-customer-id>
: ID pelanggan Google SecOps Anda.<PROJECT_ID>
: ID project Google Cloud Anda.- CHRONICLE_REGION: Setel ke region Google SecOps Anda. Nilai yang valid:
us
,asia-northeast1
,asia-south1
,asia-southeast1
,australia-southeast1
,europe
,europe-west2
,europe-west3
,europe-west6
,europe-west9
,europe-west12
,me-central1
,me-central2
,me-west1
,northamerica-northeast2
,southamerica-east1
. - POLL_INTERVAL: Interval frekuensi (dalam menit) saat fungsi dijalankan. Durasi ini harus sama dengan interval tugas Cloud Scheduler.
- Ganti kode berikut:
Simpan file
.env.yml
.
Men-deploy fungsi Cloud Run
- Buka terminal atau Cloud Shell di konsol Google Cloud .
Buka direktori deployment Anda:
cd /path/to/deployment_directory
Jalankan perintah berikut untuk men-deploy fungsi Cloud Run:
gcloud functions deploy slack-audit-to-chronicle \ --entry-point main \ --trigger-http \ --runtime python39 \ --env-vars-file .env.yml \ --timeout 300s \ --memory 512MB \ --service-account <SERVICE_ACCOUNT_EMAIL>
- Ganti
<SERVICE_ACCOUNT_EMAIL>
dengan alamat email akun layanan yang ingin Anda gunakan untuk fungsi Cloud Run.
- Ganti
Tunggu hingga deployment selesai.
Setelah di-deploy, catat URL fungsi dari output.
Menyiapkan Cloud Scheduler
- Di Google Cloud konsol, buka Cloud Scheduler > Buat tugas.
- Berikan detail konfigurasi berikut:
- Nama: Masukkan
slack-audit-scheduler
. - Region: Pilih region yang sama dengan tempat Anda men-deploy fungsi Cloud Run.
- Frekuensi: Masukkan
*/5 * * * *
(dijalankan setiap 5 menit, cocok dengan nilaiPOLL_INTERVAL
). - Zona waktu: Pilih UTC.
- Jenis target: Pilih HTTP.
- URL: Masukkan URL fungsi Cloud Run dari output deployment.
- Metode HTTP: Pilih POST.
- Header Auth: Pilih Tambahkan token OIDC.
- Akun layanan: Pilih akun layanan yang sama yang digunakan untuk fungsi Cloud Run.
- Nama: Masukkan
- Klik Buat.
Tabel Pemetaan UDM
Kolom Log | Pemetaan UDM | Logika |
---|---|---|
action |
metadata.product_event_type |
Dipetakan langsung dari kolom action dalam log mentah. |
actor.type |
principal.labels.value |
Dipetakan langsung dari kolom actor.type , dengan kunci actor.type ditambahkan. |
actor.user.email |
principal.user.email_addresses |
Dipetakan langsung dari kolom actor.user.email . |
actor.user.id |
principal.user.product_object_id |
Dipetakan langsung dari kolom actor.user.id . |
actor.user.id |
principal.user.userid |
Dipetakan langsung dari kolom actor.user.id . |
actor.user.name |
principal.user.user_display_name |
Dipetakan langsung dari kolom actor.user.name . |
actor.user.team |
principal.user.group_identifiers |
Dipetakan langsung dari kolom actor.user.team . |
context.ip_address |
principal.ip |
Dipetakan langsung dari kolom context.ip_address . |
context.location.domain |
about.resource.attribute.labels.value |
Dipetakan langsung dari kolom context.location.domain , dengan kunci context.location.domain ditambahkan. |
context.location.id |
about.resource.id |
Dipetakan langsung dari kolom context.location.id . |
context.location.name |
about.resource.name |
Dipetakan langsung dari kolom context.location.name . |
context.location.name |
about.resource.attribute.labels.value |
Dipetakan langsung dari kolom context.location.name , dengan kunci context.location.name ditambahkan. |
context.location.type |
about.resource.resource_subtype |
Dipetakan langsung dari kolom context.location.type . |
context.session_id |
network.session_id |
Dipetakan langsung dari kolom context.session_id . |
context.ua |
network.http.user_agent |
Dipetakan langsung dari kolom context.ua . |
context.ua |
network.http.parsed_user_agent |
Informasi agen pengguna yang diuraikan yang berasal dari kolom context.ua menggunakan filter parseduseragent . |
country |
principal.location.country_or_region |
Dipetakan langsung dari kolom country . |
date_create |
metadata.event_timestamp.seconds |
Stempel waktu epoch dari kolom date_create dikonversi menjadi objek stempel waktu. |
details.inviter.email |
target.user.email_addresses |
Dipetakan langsung dari kolom details.inviter.email . |
details.inviter.id |
target.user.product_object_id |
Dipetakan langsung dari kolom details.inviter.id . |
details.inviter.name |
target.user.user_display_name |
Dipetakan langsung dari kolom details.inviter.name . |
details.inviter.team |
target.user.group_identifiers |
Dipetakan langsung dari kolom details.inviter.team . |
details.reason |
security_result.description |
Dipetakan langsung dari kolom details.reason , atau jika berupa array, digabungkan dengan koma. |
details.type |
about.resource.attribute.labels.value |
Dipetakan langsung dari kolom details.type , dengan kunci details.type ditambahkan. |
details.type |
security_result.summary |
Dipetakan langsung dari kolom details.type . |
entity.app.id |
target.resource.id |
Dipetakan langsung dari kolom entity.app.id . |
entity.app.name |
target.resource.name |
Dipetakan langsung dari kolom entity.app.name . |
entity.channel.id |
target.resource.id |
Dipetakan langsung dari kolom entity.channel.id . |
entity.channel.name |
target.resource.name |
Dipetakan langsung dari kolom entity.channel.name . |
entity.channel.privacy |
target.resource.attribute.labels.value |
Dipetakan langsung dari kolom entity.channel.privacy , dengan kunci entity.channel.privacy ditambahkan. |
entity.file.filetype |
target.resource.attribute.labels.value |
Dipetakan langsung dari kolom entity.file.filetype , dengan kunci entity.file.filetype ditambahkan. |
entity.file.id |
target.resource.id |
Dipetakan langsung dari kolom entity.file.id . |
entity.file.name |
target.resource.name |
Dipetakan langsung dari kolom entity.file.name . |
entity.file.title |
target.resource.attribute.labels.value |
Dipetakan langsung dari kolom entity.file.title , dengan kunci entity.file.title ditambahkan. |
entity.huddle.date_end |
about.resource.attribute.labels.value |
Dipetakan langsung dari kolom entity.huddle.date_end , dengan kunci entity.huddle.date_end ditambahkan. |
entity.huddle.date_start |
about.resource.attribute.labels.value |
Dipetakan langsung dari kolom entity.huddle.date_start , dengan kunci entity.huddle.date_start ditambahkan. |
entity.huddle.id |
about.resource.attribute.labels.value |
Dipetakan langsung dari kolom entity.huddle.id , dengan kunci entity.huddle.id ditambahkan. |
entity.huddle.participants.0 |
about.resource.attribute.labels.value |
Dipetakan langsung dari kolom entity.huddle.participants.0 , dengan kunci entity.huddle.participants.0 ditambahkan. |
entity.huddle.participants.1 |
about.resource.attribute.labels.value |
Dipetakan langsung dari kolom entity.huddle.participants.1 , dengan kunci entity.huddle.participants.1 ditambahkan. |
entity.type |
target.resource.resource_subtype |
Dipetakan langsung dari kolom entity.type . |
entity.user.email |
target.user.email_addresses |
Dipetakan langsung dari kolom entity.user.email . |
entity.user.id |
target.user.product_object_id |
Dipetakan langsung dari kolom entity.user.id . |
entity.user.name |
target.user.user_display_name |
Dipetakan langsung dari kolom entity.user.name . |
entity.user.team |
target.user.group_identifiers |
Dipetakan langsung dari kolom entity.user.team . |
entity.workflow.id |
target.resource.id |
Dipetakan langsung dari kolom entity.workflow.id . |
entity.workflow.name |
target.resource.name |
Dipetakan langsung dari kolom entity.workflow.name . |
id |
metadata.product_log_id |
Dipetakan langsung dari kolom id . |
ip |
principal.ip |
Dipetakan langsung dari kolom ip . Ditentukan oleh logika berdasarkan kolom action . Nilai defaultnya adalah USER_COMMUNICATION , tetapi berubah menjadi nilai lain seperti USER_CREATION , USER_LOGIN , USER_LOGOUT , USER_RESOURCE_ACCESS , USER_RESOURCE_UPDATE_PERMISSIONS , atau USER_CHANGE_PERMISSIONS berdasarkan nilai action . Dikodekan secara permanen ke "SLACK_AUDIT". Ditetapkan ke "Enterprise Grid" jika date_create ada, atau ditetapkan ke "Audit Logs" jika user_id ada. Dikodekan secara permanen ke "Slack". Dikodekan secara permanen ke "REMOTE". Setel ke "SSO" jika action berisi "user_login" atau "user_logout". Jika tidak, tetapkan ke "MESIN". Tidak dipetakan dalam contoh yang diberikan. Default-nya adalah "ALLOW", tetapi disetel ke "BLOCK" jika action adalah "user_login_failed". Disetel ke "Slack" jika date_create ada, atau disetel ke "SLACK" jika user_id ada. |
user_agent |
network.http.user_agent |
Dipetakan langsung dari kolom user_agent . |
user_id |
principal.user.product_object_id |
Dipetakan langsung dari kolom user_id . |
username |
principal.user.product_object_id |
Dipetakan langsung dari kolom username . |
Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.