Raccogliere gli audit log di Slack
Questo documento spiega come importare i log di controllo di Slack in Google Security Operations utilizzando le funzioni Google Cloud Run. Il parser gestisce due formati di audit log di Slack. Innanzitutto normalizza i valori booleani e cancella i campi predefiniti. Quindi, analizza il campo "message" come JSON, gestendo i messaggi non JSON eliminandoli. A seconda della presenza di campi specifici (date_create
e user_id
), il parser applica una logica diversa per mappare i campi dei log non elaborati all'UDM, incluse informazioni su metadati, entità, rete, destinazione e informazioni, e crea un risultato di sicurezza.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Un'istanza Google SecOps
- Accesso privilegiato al tenant Slack Enterprise Grid e alla Console di amministrazione
- Accesso con privilegi alle funzioni Cloud Run e a Cloud Scheduler di GCP
Prerequisiti per la raccolta dei log di controllo di Slack (ID app, token OAuth, ID organizzazione)
- Accedi alla console di amministrazione di Slack per la tua organizzazione Enterprise Grid.
- Vai su https://api.slack.com/apps e fai clic su Crea nuova app > Da zero.
- Inserisci il nome dell'app e seleziona il tuo spazio di lavoro Slack di sviluppo.
- Fai clic su Crea app.
- Vai a OAuth e autorizzazioni nella barra laterale sinistra.
- Vai alla sezione Ambiti e aggiungi il seguente ambito del token utente:
- auditlogs:read
- Fai clic su Installa in Workspace > Consenti.
- Una volta installata, vai ad App a livello di organizzazione > Installa nell'organizzazione.
- Autorizza l'app con un account proprietario/amministratore dell'organizzazione.
- Copia e salva in modo sicuro il token OAuth utente che inizia con
xoxp-
(questo è il tuo SLACK_ADMIN_TOKEN). - Copia il tuo ID organizzazione, che puoi trovare nella console di amministrazione di Slack in Impostazioni e permessi > Impostazioni dell'organizzazione.
Configurare la directory
- Crea una nuova directory sulla macchina locale per il deployment della funzione Cloud Run.
- Scarica i seguenti file dal repository GitHub di Chronicle ingestion-scripts:
- Dalla cartella slack, scarica:
.env.yml
main.py
requirements.txt
- Dalla radice del repository, scarica l'intera directory common con tutti i relativi file:
common/__init__.py
common/auth.py
common/env_constants.py
common/ingest.py
common/status.py
common/utils.py
- Dalla cartella slack, scarica:
- Inserisci tutti i file scaricati nella directory di deployment.
La struttura di directory dovrebbe essere simile alla seguente:
deployment_directory/
├─common/
│ ├─__init__.py
│ ├─auth.py
│ ├─env_constants.py
│ ├─ingest.py
│ ├─status.py
│ └─utils.py
├─.env.yml
├─main.py
└─requirements.txt
Crea secret in Google Secret Manager
- Nella Google Cloud console, vai a Sicurezza > Secret Manager.
- Fai clic su Crea secret.
- Fornisci i seguenti dettagli di configurazione per il service account Chronicle:
- Nome: inserisci
chronicle-service-account
. - Valore segreto: incolla i contenuti del file JSON di autenticazione dell'importazione di Google SecOps.
- Nome: inserisci
- Fai clic su Crea secret.
Copia il nome della risorsa secret nel seguente formato:
projects/<PROJECT_ID>/secrets/chronicle-service-account/versions/latest
Fai di nuovo clic su Crea secret per creare un secondo secret.
Fornisci i seguenti dettagli di configurazione per il token Slack:
- Nome: inserisci
slack-admin-token
. - Valore del segreto: incolla il token OAuth utente di Slack (che inizia con
xoxp-
).
- Nome: inserisci
Fai clic su Crea secret.
Copia il nome della risorsa secret nel seguente formato:
projects/<PROJECT_ID>/secrets/slack-admin-token/versions/latest
Impostazione delle variabili di ambiente runtime richieste
- Apri il file
.env.yml
nella directory di deployment. Configura le variabili di ambiente con i tuoi valori:
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"
- Sostituisci quanto segue:
<your-chronicle-customer-id>
: il tuo ID cliente Google SecOps.<PROJECT_ID>
: il tuo ID progetto Google Cloud .- CHRONICLE_REGION: impostalo sulla tua regione Google SecOps. Valori validi:
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: intervallo di frequenza (in minuti) con cui viene eseguita la funzione. Questa durata deve corrispondere all'intervallo del job Cloud Scheduler.
- Sostituisci quanto segue:
Salva il file
.env.yml
.
Deployment della funzione Cloud Run
- Apri un terminale o Cloud Shell nella console Google Cloud .
Vai alla directory di deployment:
cd /path/to/deployment_directory
Esegui questo comando per eseguire il deployment della funzione 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>
- Sostituisci
<SERVICE_ACCOUNT_EMAIL>
con l'indirizzo email del account di servizio che vuoi che utilizzi la tua funzione Cloud Run.
- Sostituisci
Attendi il completamento del deployment.
Una volta eseguito il deployment, prendi nota dell'URL della funzione dall'output.
Configura Cloud Scheduler
- Nella Google Cloud console, vai a Cloud Scheduler > Crea job.
- Fornisci i seguenti dettagli di configurazione:
- Nome: inserisci
slack-audit-scheduler
. - Regione: seleziona la stessa regione in cui hai eseguito il deployment della funzione Cloud Run.
- Frequenza: inserisci
*/5 * * * *
(l'esecuzione avviene ogni 5 minuti, in corrispondenza del valorePOLL_INTERVAL
). - Fuso orario: seleziona UTC.
- Tipo di destinazione: seleziona HTTP.
- URL: inserisci l'URL della funzione Cloud Run dall'output del deployment.
- Metodo HTTP: seleziona POST.
- Intestazione di autenticazione: seleziona Aggiungi token OIDC.
- Service account: seleziona lo stesso account di servizio utilizzato per la funzione Cloud Run.
- Nome: inserisci
- Fai clic su Crea.
Tabella di mappatura UDM
Campo log | Mappatura UDM | Logic |
---|---|---|
action |
metadata.product_event_type |
Mappato direttamente dal campo action nel log non elaborato. |
actor.type |
principal.labels.value |
Mappato direttamente dal campo actor.type , con l'aggiunta della chiave actor.type . |
actor.user.email |
principal.user.email_addresses |
Mappato direttamente dal campo actor.user.email . |
actor.user.id |
principal.user.product_object_id |
Mappato direttamente dal campo actor.user.id . |
actor.user.id |
principal.user.userid |
Mappato direttamente dal campo actor.user.id . |
actor.user.name |
principal.user.user_display_name |
Mappato direttamente dal campo actor.user.name . |
actor.user.team |
principal.user.group_identifiers |
Mappato direttamente dal campo actor.user.team . |
context.ip_address |
principal.ip |
Mappato direttamente dal campo context.ip_address . |
context.location.domain |
about.resource.attribute.labels.value |
Mappato direttamente dal campo context.location.domain , con l'aggiunta della chiave context.location.domain . |
context.location.id |
about.resource.id |
Mappato direttamente dal campo context.location.id . |
context.location.name |
about.resource.name |
Mappato direttamente dal campo context.location.name . |
context.location.name |
about.resource.attribute.labels.value |
Mappato direttamente dal campo context.location.name , con l'aggiunta della chiave context.location.name . |
context.location.type |
about.resource.resource_subtype |
Mappato direttamente dal campo context.location.type . |
context.session_id |
network.session_id |
Mappato direttamente dal campo context.session_id . |
context.ua |
network.http.user_agent |
Mappato direttamente dal campo context.ua . |
context.ua |
network.http.parsed_user_agent |
Informazioni sull'user agent analizzate derivate dal campo context.ua utilizzando il filtro parseduseragent . |
country |
principal.location.country_or_region |
Mappato direttamente dal campo country . |
date_create |
metadata.event_timestamp.seconds |
Il timestamp Unix del campo date_create viene convertito in un oggetto timestamp. |
details.inviter.email |
target.user.email_addresses |
Mappato direttamente dal campo details.inviter.email . |
details.inviter.id |
target.user.product_object_id |
Mappato direttamente dal campo details.inviter.id . |
details.inviter.name |
target.user.user_display_name |
Mappato direttamente dal campo details.inviter.name . |
details.inviter.team |
target.user.group_identifiers |
Mappato direttamente dal campo details.inviter.team . |
details.reason |
security_result.description |
Mappato direttamente dal campo details.reason o, se si tratta di un array, concatenato con virgole. |
details.type |
about.resource.attribute.labels.value |
Mappato direttamente dal campo details.type , con l'aggiunta della chiave details.type . |
details.type |
security_result.summary |
Mappato direttamente dal campo details.type . |
entity.app.id |
target.resource.id |
Mappato direttamente dal campo entity.app.id . |
entity.app.name |
target.resource.name |
Mappato direttamente dal campo entity.app.name . |
entity.channel.id |
target.resource.id |
Mappato direttamente dal campo entity.channel.id . |
entity.channel.name |
target.resource.name |
Mappato direttamente dal campo entity.channel.name . |
entity.channel.privacy |
target.resource.attribute.labels.value |
Mappato direttamente dal campo entity.channel.privacy , con l'aggiunta della chiave entity.channel.privacy . |
entity.file.filetype |
target.resource.attribute.labels.value |
Mappato direttamente dal campo entity.file.filetype , con l'aggiunta della chiave entity.file.filetype . |
entity.file.id |
target.resource.id |
Mappato direttamente dal campo entity.file.id . |
entity.file.name |
target.resource.name |
Mappato direttamente dal campo entity.file.name . |
entity.file.title |
target.resource.attribute.labels.value |
Mappato direttamente dal campo entity.file.title , con l'aggiunta della chiave entity.file.title . |
entity.huddle.date_end |
about.resource.attribute.labels.value |
Mappato direttamente dal campo entity.huddle.date_end , con l'aggiunta della chiave entity.huddle.date_end . |
entity.huddle.date_start |
about.resource.attribute.labels.value |
Mappato direttamente dal campo entity.huddle.date_start , con l'aggiunta della chiave entity.huddle.date_start . |
entity.huddle.id |
about.resource.attribute.labels.value |
Mappato direttamente dal campo entity.huddle.id , con l'aggiunta della chiave entity.huddle.id . |
entity.huddle.participants.0 |
about.resource.attribute.labels.value |
Mappato direttamente dal campo entity.huddle.participants.0 , con l'aggiunta della chiave entity.huddle.participants.0 . |
entity.huddle.participants.1 |
about.resource.attribute.labels.value |
Mappato direttamente dal campo entity.huddle.participants.1 , con l'aggiunta della chiave entity.huddle.participants.1 . |
entity.type |
target.resource.resource_subtype |
Mappato direttamente dal campo entity.type . |
entity.user.email |
target.user.email_addresses |
Mappato direttamente dal campo entity.user.email . |
entity.user.id |
target.user.product_object_id |
Mappato direttamente dal campo entity.user.id . |
entity.user.name |
target.user.user_display_name |
Mappato direttamente dal campo entity.user.name . |
entity.user.team |
target.user.group_identifiers |
Mappato direttamente dal campo entity.user.team . |
entity.workflow.id |
target.resource.id |
Mappato direttamente dal campo entity.workflow.id . |
entity.workflow.name |
target.resource.name |
Mappato direttamente dal campo entity.workflow.name . |
id |
metadata.product_log_id |
Mappato direttamente dal campo id . |
ip |
principal.ip |
Mappato direttamente dal campo ip . Determinato dalla logica in base al campo action . Il valore predefinito è USER_COMMUNICATION , ma cambia in altri valori come USER_CREATION , USER_LOGIN , USER_LOGOUT , USER_RESOURCE_ACCESS , USER_RESOURCE_UPDATE_PERMISSIONS o USER_CHANGE_PERMISSIONS in base al valore di action . Codificato in modo permanente su "SLACK_AUDIT". Imposta "Enterprise Grid" se esiste date_create , altrimenti imposta "Log di controllo" se esiste user_id . Codificato in modo permanente su "Slack". Codificato come "REMOTE". Imposta "SSO" se action contiene "user_login" o "user_logout". In caso contrario, imposta "MACHINE". Non mappato negli esempi forniti. Il valore predefinito è "ALLOW", ma è impostato su "BLOCK" se action è "user_login_failed". Imposta "Slack" se esiste date_create , altrimenti imposta "SLACK" se esiste user_id . |
user_agent |
network.http.user_agent |
Mappato direttamente dal campo user_agent . |
user_id |
principal.user.product_object_id |
Mappato direttamente dal campo user_id . |
username |
principal.user.product_object_id |
Mappato direttamente dal campo username . |
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.