Raccogliere i log del framework di scansione dei file
Questo documento spiega come importare i log di File Scanning Framework in Google Security Operations utilizzando Google Cloud Storage V2.
File Scanning Framework (FSF) è una soluzione di scansione ricorsiva dei file modulare open source sviluppata da Emerson Electric Co. FSF utilizza un'architettura client-server per analizzare i file e generare risultati di scansione JSON dettagliati, inclusi metadati dei file, corrispondenze di firme YARA, sotto-oggetti estratti e metadati specifici del modulo.
Prima di iniziare
Assicurati di soddisfare i seguenti prerequisiti:
- Un'istanza Google SecOps
- Un progetto GCP con l'API Cloud Storage abilitata
- Autorizzazioni per creare e gestire bucket GCS
- Autorizzazioni per gestire le policy IAM nei bucket GCS
- Un'istanza del server FSF di cui è stato eseguito il deployment con accesso in scrittura alla directory dei log
- Accesso root o sudo all'host del server FSF
Creazione di un bucket Google Cloud Storage
- Vai alla console Google Cloud.
- Seleziona il tuo progetto o creane uno nuovo.
- Nel menu di navigazione, vai a Cloud Storage > Bucket.
- Fai clic su Crea bucket.
Fornisci i seguenti dettagli di configurazione:
Impostazione Valore Assegna un nome al bucket Inserisci un nome univoco globale (ad esempio fsf-logs-secops).Tipo di località Scegli in base alle tue esigenze (regione singola, due regioni, più regioni). Località Seleziona la posizione (ad esempio, us-central1).Classe di archiviazione Standard (consigliato per i log ad accesso frequente). Controllo dell'accesso Uniforme (consigliato). Strumenti di protezione (Facoltativo) Abilita il controllo delle versioni degli oggetti o la policy di conservazione. Fai clic su Crea.
Configurare la directory di output dei log FSF
FSF scrive i risultati della scansione JSON in una directory dei log configurabile. Configura una directory dedicata per l'importazione di Google SecOps.
- Connettiti all'host del server FSF tramite SSH.
Apri il file di configurazione del server FSF:
sudo nano /opt/fsf/fsf-server/conf/config.pyIndividua il dizionario
SCANNER_CONFIG.Aggiorna il parametro
LOG_PATHa una directory dedicata:SCANNER_CONFIG = { 'LOG_PATH': '/var/log/fsf', 'YARA_PATH': '/opt/fsf/fsf-server/yara/rules.yara', 'PID_PATH': '/tmp/scanner.pid', 'EXPORT_PATH': '/tmp', 'TIMEOUT': 60, 'MAX_DEPTH': 10 }Salva e chiudi il file.
Crea la directory dei log con le autorizzazioni appropriate:
sudo mkdir -p /var/log/fsf sudo chown -R fsf:fsf /var/log/fsf sudo chmod 755 /var/log/fsfRiavvia il server FSF per applicare le modifiche:
sudo systemctl restart fsfVerifica che FSF stia scrivendo i log nella nuova directory:
ls -lh /var/log/fsf/
Installa e configura Fluentd
Fluentd seguirà i file di log FSF e li invierà a Google Cloud Storage.
Installa Fluentd
Sul server host FSF, installa Fluentd (td-agent):
curl -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-jammy-td-agent4.sh | shInstalla il plug-in di output GCS:
sudo td-agent-gem install fluent-plugin-gcsVerifica l'installazione del plug-in:
td-agent-gem list | grep fluent-plugin-gcs
Crea un account di servizio Google Cloud per Fluentd
- Nella console Google Cloud, vai a IAM e amministrazione > Service Accounts.
- Fai clic su Crea account di servizio.
- Fornisci i seguenti dettagli di configurazione:
- Nome del service account: inserisci
fsf-fluentd-shipper. - Descrizione service account: inserisci
Service account for Fluentd to ship FSF logs to GCS.
- Nome del service account: inserisci
- Fai clic su Crea e continua.
- Nella sezione Concedi a questo account di servizio l'accesso al progetto:
- Fai clic su Seleziona un ruolo.
- Cerca e seleziona Amministratore oggetti di archiviazione.
- Fai clic su Continua.
- Fai clic su Fine.
Crea la chiave dell'account di servizio
- Nell'elenco Service Accounts (Account di servizio), fai clic sul service account (
fsf-fluentd-shipper). - Vai alla scheda Chiavi.
- Fai clic su Aggiungi chiave > Crea nuova chiave.
- Seleziona JSON come tipo di chiave.
- Fai clic su Crea.
- Il file della chiave JSON verrà scaricato sul computer.
Trasferisci il file della chiave all'host del server FSF:
scp /path/to/downloaded-key.json user@fsf-server:/etc/td-agent/gcp-key.jsonImposta le autorizzazioni appropriate per il file della chiave:
sudo chown td-agent:td-agent /etc/td-agent/gcp-key.json sudo chmod 600 /etc/td-agent/gcp-key.json
Concedi autorizzazioni IAM sul bucket GCS
- Vai a Cloud Storage > Bucket.
- Fai clic sul nome del bucket (
fsf-logs-secops). - Vai alla scheda Autorizzazioni.
- Fai clic su Concedi l'accesso.
- Fornisci i seguenti dettagli di configurazione:
- Aggiungi entità: inserisci l'email del account di servizio (ad es.
fsf-fluentd-shipper@PROJECT_ID.iam.gserviceaccount.com). - Assegna i ruoli: seleziona Storage Object Admin.
- Aggiungi entità: inserisci l'email del account di servizio (ad es.
- Fai clic su Salva.
Configura Fluentd
Sull'host del server FSF, crea un file di configurazione Fluentd:
sudo nano /etc/td-agent/td-agent.confAggiungi la seguente configurazione:
# Tail FSF JSON logs <source> @type tail path /var/log/fsf/*.log pos_file /var/log/td-agent/fsf.log.pos tag fsf.scan read_from_head true <parse> @type json time_key timestamp time_format %Y-%m-%dT%H:%M:%S.%L%z </parse> </source> # Ship to Google Cloud Storage <match fsf.scan> @type gcs project YOUR_GCP_PROJECT_ID keyfile /etc/td-agent/gcp-key.json bucket fsf-logs-secops object_key_format %{path}%{time_slice}_%{index}.%{file_extension} path fsf-logs/ <buffer tag,time> @type file path /var/log/td-agent/buffer/gcs timekey 3600 timekey_wait 10m timekey_use_utc true chunk_limit_size 10MB </buffer> <format> @type json </format> store_as json auto_create_bucket false </match>Sostituisci
YOUR_GCP_PROJECT_IDcon l'ID progetto GCP effettivo.Salva e chiudi il file.
Crea la directory del buffer:
sudo mkdir -p /var/log/td-agent/buffer/gcs sudo chown -R td-agent:td-agent /var/log/td-agent/bufferRiavvia Fluentd per applicare la configurazione:
sudo systemctl restart td-agentAttiva l'avvio di Fluentd all'avvio:
sudo systemctl enable td-agentVerifica che Fluentd sia in esecuzione:
sudo systemctl status td-agent
Verifica l'invio dei log
Controlla i log di Fluentd per rilevare errori:
sudo tail -f /var/log/td-agent/td-agent.logAttiva una scansione FSF di test per generare i log:
echo "test content" > /tmp/test.txt /opt/fsf/fsf-client/fsf_client.py /tmp/test.txt --suppress-reportAttendi 1-2 minuti affinché Fluentd elabori e invii i log.
Nella console GCP, vai a Cloud Storage > Bucket.
Fai clic sul nome del bucket (
fsf-logs-secops).Vai al prefisso
fsf-logs/.Verifica che i file JSON vengano creati con i timestamp.
Scarica e controlla un file per verificare che contenga i risultati della scansione FSF in formato JSON.
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.
Recuperare l'email del account di servizio
- Vai a Impostazioni SIEM > Feed.
- Fai clic su Aggiungi nuovo feed.
- Fai clic su Configura un singolo feed.
- Nel campo Nome feed, inserisci un nome per il feed (ad esempio,
FSF File Scanning Logs). - Seleziona Google Cloud Storage V2 come Tipo di origine.
- Seleziona File Scanning Framework come Tipo di log.
Fai clic su Ottieni service account. Verrà visualizzata un'email univoca del account di servizio, ad esempio:
secops-12345678@secops-gcp-prod.iam.gserviceaccount.comCopia l'indirizzo email da utilizzare nel passaggio successivo.
Fai clic su Avanti.
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://fsf-logs-secops/fsf-logs/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 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.
Fai clic su Avanti.
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.
- Vai a Cloud Storage > Bucket.
- Fai clic sul nome del bucket (
fsf-logs-secops). - Vai alla scheda Autorizzazioni.
- Fai clic su Concedi l'accesso.
- Fornisci i seguenti dettagli di configurazione:
- Aggiungi entità: incolla l'email del account di servizio Google SecOps.
- Assegna ruoli: seleziona Visualizzatore oggetti Storage.
- Fai clic su Salva.
Verifica l'importazione
- Attendi 10-15 minuti per il completamento dell'importazione iniziale.
- In Google SecOps, vai a Impostazioni SIEM > Feed.
- Individua il feed (
FSF File Scanning Logs). - Verifica che lo stato sia Attivo.
- Fai clic sul nome del feed per visualizzare le metriche di importazione.
- Verifica che il conteggio Eventi inseriti sia in aumento.
- Vai a Ricerca in Google SecOps.
Esegui una query di ricerca per verificare che i log FSF vengano inseriti:
metadata.log_type = "FILE_SCANNING_FRAMEWORK"Verifica che i risultati della scansione FSF vengano visualizzati nei risultati di ricerca.
Risoluzione dei problemi
Nessun log visualizzato in GCS
Verifica che FSF scriva i log in
/var/log/fsf/:ls -lh /var/log/fsf/ tail -f /var/log/fsf/*.logControlla i log di Fluentd per rilevare errori:
sudo tail -f /var/log/td-agent/td-agent.logVerifica che la chiave del account di servizio GCP sia valida e disponga delle autorizzazioni corrette.
Verifica che il nome del bucket nella configurazione di Fluentd corrisponda al nome effettivo del bucket.
Errori di autorizzazione di Fluentd
- Verifica che il account di servizio (
fsf-fluentd-shipper) abbia il ruolo Amministratore oggetti Storage sul bucket. - Controlla che il percorso della chiave nella configurazione di Fluentd sia corretto.
Verifica che il file della chiave abbia la proprietà e le autorizzazioni corrette:
ls -l /etc/td-agent/gcp-key.json
Google SecOps non esegue l'importazione dei log
- Verifica che il account di servizio Google SecOps abbia il ruolo Visualizzatore oggetti Storage sul bucket.
- Verifica che l'URI del bucket nella configurazione del feed sia corretto e includa la barra finale.
- Verifica che i file esistano nel bucket GCS nel percorso del prefisso specificato.
- Controlla lo stato del feed in Impostazioni SIEM > Feed per verificare la presenza di messaggi di errore.
Log FSF non nel formato previsto
- Verifica che FSF sia configurato per scrivere l'output JSON (comportamento predefinito).
- Verifica che la sezione Fluentd
<parse>sia configurata con@type json. Ispeziona manualmente un file di log per verificare che contenga un JSON valido:
head -n 1 /var/log/fsf/*.log | jq .
Tabella di mappatura UDM
| Campo log | Mappatura UDM | Logic |
|---|---|---|
| CompressType_label, compressed_parents | about.labels | Unito da CompressType_label (chiave "Tipo di compressione", valore da Object.EXTRACT_ZIP.Object_0.Tipo di compressione se il messaggio contiene "Tipo di compressione") e compressed_parents (chiave "File padre compressi", concatenato da Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.additional_info.compressed_parents) |
| Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.MD5, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.MD5, Object.EXTRACT_SWF.META_BASIC_INFO.MD5, Object.EXTRACT_GZIP.META_BASIC_INFO.MD5, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.MD5 | intermediary.file.md5 | Valore di Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.MD5 se EXTRACT_EMBEDDED è presente, altrimenti Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.MD5 se EXTRACT_ZIP è presente, altrimenti Object.EXTRACT_SWF.META_BASIC_INFO.MD5 se EXTRACT_SWF è presente, altrimenti Object.EXTRACT_GZIP.META_BASIC_INFO.MD5 se EXTRACT_GZIP è presente, altrimenti Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.MD5 |
| Object.EXTRACT_EMBEDDED.Object_0.Description | intermediary.file.mime_type | Valore copiato direttamente |
| Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA1, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA1, Object.EXTRACT_SWF.META_BASIC_INFO.SHA1, Object.EXTRACT_GZIP.META_BASIC_INFO.SHA1, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA1 | intermediary.file.sha1 | Valore di Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA1 se EXTRACT_EMBEDDED è presente, altrimenti Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA1 se EXTRACT_ZIP è presente, altrimenti Object.EXTRACT_SWF.META_BASIC_INFO.SHA1 se EXTRACT_SWF è presente, altrimenti Object.EXTRACT_GZIP.META_BASIC_INFO.SHA1 se EXTRACT_GZIP è presente, altrimenti Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA1 |
| Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA256, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA256, Object.EXTRACT_SWF.META_BASIC_INFO.SHA256, Object.EXTRACT_GZIP.META_BASIC_INFO.SHA256, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA256 | intermediary.file.sha256 | Valore di Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.SHA256 se EXTRACT_EMBEDDED è presente, altrimenti Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.SHA256 se EXTRACT_ZIP è presente, altrimenti Object.EXTRACT_SWF.META_BASIC_INFO.SHA256 se EXTRACT_SWF è presente, altrimenti Object.EXTRACT_GZIP.META_BASIC_INFO.SHA256 se EXTRACT_GZIP è presente, altrimenti Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.SHA256 |
| Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.Size, Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.Size, Object.EXTRACT_SWF.META_BASIC_INFO.Size, Object.EXTRACT_GZIP.META_BASIC_INFO.Size, Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.Size | intermediary.file.size | Valore di Object.EXTRACT_EMBEDDED.Object_0.META_BASIC_INFO.Size se EXTRACT_EMBEDDED è presente, altrimenti Object.EXTRACT_ZIP.Object_0.META_BASIC_INFO.Size se EXTRACT_ZIP è presente, altrimenti Object.EXTRACT_SWF.META_BASIC_INFO.Size se EXTRACT_SWF è presente, altrimenti Object.EXTRACT_GZIP.META_BASIC_INFO.Size se EXTRACT_GZIP è presente, altrimenti Object.EXTRACT_CAB.Object_0.META_BASIC_INFO.Size; privato di " .*" finale e convertito in uinteger |
| Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.scan_id | intermediary.resource.id | Valore copiato direttamente |
| Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.permalink | intermediary.url | Valore copiato direttamente |
| Object.META_EMERSON_INFO.results | intermediary.user.email_addresses | Unito da matched_email nell'array dei risultati |
| Summary.Observations | metadata.description | Concatenato dall'array con il separatore ", ", virgola iniziale rimossa |
| Ora scansione | metadata.event_timestamp | Convertito utilizzando il filtro per data con il formato aaaa-MM-gg HH:mm:ss |
| Origine | metadata.event_type | Impostato su "SCAN_FILE" se Source non è vuoto, altrimenti "GENERIC_EVENT" |
| Object.META_VT_CACHE._id | metadata.product_log_id | Valore copiato direttamente |
| result.ad_data.message | network.http.response_code | Estratto come numero intero utilizzando il pattern grok INT da result.ad_data.message |
| Origine | principal.hostname | Valore copiato direttamente |
| Object.META_EMERSON_INFO.result_summary, Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.verbose_msg | security_result.summary | Imposta su Object.META_EMERSON_INFO.result_summary se presente, altrimenti Object.EXTRACT_ZIP.Object_0.META_VT_CACHE.vt_data.verbose_msg |
| Nome del file | target.file.full_path | Valore copiato direttamente |
| Object.META_BASIC_INFO.MD5 | target.file.md5 | Valore copiato direttamente |
| Summary.Yara | target.file.mime_type | Estratto dal primo indice di Summary.Yara, convertito in maiuscolo e "FT_" rimosso se Yara è presente, altrimenti impostato su "ZIP" se EXTRACT_ZIP è presente, "SWF" se EXTRACT_SWF è presente, "GZIP" se EXTRACT_GZIP è presente, "CAB" se EXTRACT_CAB è presente |
| Object.META_BASIC_INFO.SHA1, Object.META_VT_CACHE.SHA1 | target.file.sha1 | Valore di Object.META_BASIC_INFO.SHA1 se non è vuoto, altrimenti Object.META_VT_CACHE.SHA1 |
| Object.META_BASIC_INFO.SHA256 | target.file.sha256 | Valore copiato direttamente |
| Object.META_BASIC_INFO.Size | target.file.size | Eliminato " .*" finale e convertito in uinteger |
| metadata.vendor_name | Impostato su "EMERSON" | |
| metadata.product_name | Imposta su "FILE SCANNING FRAMEWORK" |
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.