Raccogliere i log WAF di Fastly

Supportato in:

Panoramica

Questo parser estrae i campi dai log JSON di Fastly WAF, li trasforma e rinomina e li mappa all'UDM. Gestisce vari tipi di dati, converte i livelli di gravità e classifica gli eventi in base alle informazioni su IP e nome host disponibili. Gestisce inoltre potenziali errori di analisi e elimina le voci di log con formato non corretto.

Prima di iniziare

  • Assicurati di avere un'istanza Google SecOps.
  • Un account Fastly con accesso per configurare le impostazioni WAF.

Configura un feed in Google SecOps per importare i log WAF di Fastly

  1. Vai a Impostazioni SIEM > Feed.
  2. Fai clic su Aggiungi nuovo.
  3. Nel campo Nome feed, inserisci un nome per il feed (ad esempio Log WAF Fastly).
  4. Seleziona Webhook come Tipo di origine.
  5. Seleziona Fastly WAF come Tipo di log.
  6. Fai clic su Avanti.
  7. (Facoltativo) Specifica i valori per i seguenti parametri di input:
    • Delimitatore di split: il delimitatore utilizzato per separare le righe di log, ad esempio \n.
    • Spazio dei nomi degli asset: lo spazio dei nomi degli asset.
    • Etichette di importazione: l'etichetta applicata agli eventi di questo feed.
  8. Fai clic su Avanti.
  9. Controlla la configurazione del feed nella schermata Concludi e poi fai clic su Invia.
  10. Fai clic su Genera chiave segreta per generare una chiave segreta per autenticare questo feed.
  11. Copia e memorizza la chiave segreta. Non potrai più visualizzare questa chiave segreta. Se necessario, puoi rigenerare una nuova chiave segreta, ma questa azione rende obsoleta la chiave segreta precedente.
  12. Nella scheda Dettagli, copia l'URL dell'endpoint del feed dal campo Informazioni sull'endpoint. Devi specificare questo URL endpoint nell'applicazione client.
  13. Fai clic su Fine.

Crea una chiave API per il feed webhook

  1. Vai alla console Google Cloud > Credenziali.

    Vai a credenziali

  2. Fai clic su Crea credenziali e poi seleziona Chiave API.

  3. Limita l'accesso della chiave API all'API Google Security Operations.

Specifica l'URL dell'endpoint

  1. Nell'applicazione client, specifica l'URL dell'endpoint HTTPS fornito nel feed webhook.
  2. Attiva l'autenticazione specificando la chiave API e la chiave segreta nell'intestazione personalizzata nel seguente formato:

    X-goog-api-key = API_KEY
    X-Webhook-Access-Key = SECRET
    

    Consiglio: specifica la chiave API come intestazione anziché nell'URL.

  3. Se il client webhook non supporta le intestazioni personalizzate, puoi specificare la chiave API e la chiave segreta utilizzando parametri di ricerca nel seguente formato:

    ENDPOINT_URL?key=API_KEY&secret=SECRET
    

    Sostituisci quanto segue:

    • ENDPOINT_URL: l'URL dell'endpoint del feed.
    • API_KEY: la chiave API per l'autenticazione in Google Security Operations.
    • SECRET: la chiave segreta che hai generato per autenticare il feed.

Configurare il webhook in Fastly

  1. Accedi a Fastly.
  2. (Facoltativo) Seleziona un sito nel menu Siti (se ne hai più di uno).
  3. Seleziona Gestisci > Integrazioni del sito.
  4. Fai clic su Aggiungi integrazione del sito.
  5. Seleziona Webhook generico.
  6. URL webhook: inserisci ENDPOINT_URL di Google SecOps, seguito da API_KEY e SECRET.
  7. Posizionamento avviso: seleziona Tutte le attività o Attività specifiche.
  8. (Facoltativo) Se hai selezionato Attività specifica, vai al menu Attività e seleziona i tipi di attività che vuoi che l'webhook invii.
  9. Fai clic su Crea integrazione del sito.

Tabella di mappatura UDM

Campo log Mappatura UDM Logica
anomaly_score security_result.detection_fields[].key: "anomaly"
security_result.detection_fields[].value: anomaly_score
Se waf.score.anomaly è 0 o vuoto e anomaly_score non è vuoto o 0, il valore anomaly_score viene utilizzato per compilare l'array security_result.detection_fields con una chiave "anomaly" e il valore del campo anomaly_score.
cache_status additional.fields[].key: "cache_status"
additional.fields[].value.string_value: cache_status
Il valore cache_status viene utilizzato per compilare l'array additional.fields con una chiave "cache_status" e il valore del campo cache_status.
client_ip principal.ip: client_ip Il campo client_ip è mappato a principal.ip.
connection.fastly_is_edge additional.fields[].key: "fastly_is_edge"
additional.fields[].value.bool_value: connection.fastly_is_edge
Il valore connection.fastly_is_edge viene utilizzato per compilare l'array additional.fields con una chiave "fastly_is_edge" e il valore del campo connection.fastly_is_edge.
connection.fastly_is_shield additional.fields[].key: "fastly_is_shield"
additional.fields[].value.bool_value: connection.fastly_is_shield
Il valore connection.fastly_is_shield viene utilizzato per compilare l'array additional.fields con una chiave "fastly_is_shield" e il valore del campo connection.fastly_is_shield.
connection.request_tls_version network.tls.version: connection.request_tls_version Il campo connection.request_tls_version è mappato a network.tls.version.
fastly.server target.hostname: fastly.server Il campo fastly.server è mappato a target.hostname.
fastly.service_id additional.fields[].key: "service_id"
additional.fields[].value.string_value: fastly.service_id
Il valore fastly.service_id viene utilizzato per compilare l'array additional.fields con una chiave "service_id" e il valore del campo fastly.service_id.
geo.city principal.location.city: geo.city Il campo geo.city è mappato a principal.location.city.
geo.country principal.location.country_or_region: geo.country Il campo geo.country è mappato a principal.location.country_or_region.
geo.location principal.location.region_latitude: estratto da geo.location
principal.location.region_longitude: estratto da geo.location
La latitudine e la longitudine vengono estratte dal campo geo.location utilizzando un'espressione regolare e mappate rispettivamente a principal.location.region_latitude e principal.location.region_longitude.
geo.region principal.location.state: geo.region Il campo geo.region è mappato a principal.location.state.
host principal.hostname: host Il campo host è mappato a principal.hostname.
request_headers.accept_charset additional.fields[].key: "accept_charset"
additional.fields[].value.string_value: request_headers.accept_charset
Il valore request_headers.accept_charset viene utilizzato per compilare l'array additional.fields con una chiave "accept_charset" e il valore del campo request_headers.accept_charset.
request_headers.accept_language additional.fields[].key: "accept_language"
additional.fields[].value.string_value: request_headers.accept_language
Il valore request_headers.accept_language viene utilizzato per compilare l'array additional.fields con una chiave "accept_language" e il valore del campo request_headers.accept_language.
request_headers.referer network.http.referral_url: request_headers.referer Il campo request_headers.referer è mappato a network.http.referral_url.
request_headers.user_agent network.http.user_agent: request_headers.user_agent Il campo request_headers.user_agent è mappato a network.http.user_agent.
request_id metadata.product_log_id: request_id Il campo request_id è mappato a metadata.product_log_id.
request_method network.http.method: request_method Il campo request_method è mappato a network.http.method.
response_headers.cache_control additional.fields[].key: "cache_control"
additional.fields[].value.string_value: response_headers.cache_control
Il valore response_headers.cache_control viene utilizzato per compilare l'array additional.fields con una chiave "cache_control" e il valore del campo response_headers.cache_control.
response_headers.content_type additional.fields[].key: "content_type"
additional.fields[].value.string_value: response_headers.content_type
Il valore response_headers.content_type viene utilizzato per compilare l'array additional.fields con una chiave "content_type" e il valore del campo response_headers.content_type.
response_state additional.fields[].key: "response_state"
additional.fields[].value.string_value: response_state
Il valore response_state viene utilizzato per compilare l'array additional.fields con una chiave "response_state" e il valore del campo response_state.
response_status network.http.response_code: response_status Il campo response_status è mappato a network.http.response_code se il campo status è vuoto.
rule_id security_result.rule_id: rule_id Se waf.rule_id è vuoto, il valore rule_id viene utilizzato per compilare security_result.rule_id.
severity waf.severity: severity Il valore del campo severity viene copiato in waf.severity.
size_bytes.request_header network.sent_bytes: size_bytes.request_header Il campo size_bytes.request_header è mappato a network.sent_bytes.
size_bytes.response_header network.received_bytes: size_bytes.response_header Il campo size_bytes.response_header è mappato a network.received_bytes.
status network.http.response_code: status Il campo status è mappato a network.http.response_code.
timestamp metadata.event_timestamp: timestamp Il campo timestamp viene analizzato e mappato a metadata.event_timestamp.
url target.url: url Il campo url è mappato a target.url.
waf.blocked security_result.action: derivato Se waf.blocked è false, security_result.action è impostato su "ALLOW". Se waf.blocked è true, security_result.action è impostato su "BLOCK".
waf.executed security_result.detection_fields[].key: "executed"
security_result.detection_fields[].value: waf.executed
Il valore waf.executed viene utilizzato per compilare l'array security_result.detection_fields con una chiave "executed" e il valore del campo waf.executed.
waf.failures security_result.detection_fields[].key: "failures"
security_result.detection_fields[].value: waf.failures
Il valore waf.failures viene utilizzato per compilare l'array security_result.detection_fields con una chiave "errori" e il valore del campo waf.failures.
waf.logged security_result.detection_fields[].key: "logged"
security_result.detection_fields[].value: waf.logged
Il valore waf.logged viene utilizzato per compilare l'array security_result.detection_fields con una chiave "logged" e il valore del campo waf.logged.
waf.message metadata.description: waf.message Se waf.message non è vuoto, viene mappato a metadata.description.
waf.rule_id security_result.rule_id: waf.rule_id Se waf.rule_id non è vuoto, viene mappato a security_result.rule_id.
waf.score.anomaly security_result.detection_fields[].key: "anomaly"
security_result.detection_fields[].value: waf.score.anomaly
Se waf.score.anomaly non è 0 e non è vuoto, il valore viene utilizzato per compilare l'array security_result.detection_fields con una chiave "anomaly" e il valore del campo waf.score.anomaly.
waf.score.http_violation security_result.detection_fields[].key: "http_violation"
security_result.detection_fields[].value: waf.score.http_violation
Se waf.score.http_violation non è 0 e non è vuoto, il valore viene utilizzato per compilare l'array security_result.detection_fields.
waf.score.lfi security_result.detection_fields[].key: "lfi"
security_result.detection_fields[].value: waf.score.lfi
Logica simile a waf.score.http_violation.
waf.score.php_injection security_result.detection_fields[].key: "php_injection"
security_result.detection_fields[].value: waf.score.php_injection
Logica simile a waf.score.http_violation.
waf.score.rce security_result.detection_fields[].key: "rce"
security_result.detection_fields[].value: waf.score.rce
Logica simile a waf.score.http_violation.
waf.score.rfi security_result.detection_fields[].key: "rfi"
security_result.detection_fields[].value: waf.score.rfi
Logica simile a waf.score.http_violation.
waf.score.session_fixation security_result.detection_fields[].key: "session_fixation"
security_result.detection_fields[].value: waf.score.session_fixation
Logica simile a waf.score.http_violation.
waf.score.sql_injection security_result.detection_fields[].key: "sql_injection"
security_result.detection_fields[].value: waf.score.sql_injection
Logica simile a waf.score.http_violation.
waf.score.xss security_result.detection_fields[].key: "xss"
security_result.detection_fields[].value: waf.score.xss
Logica simile a waf.score.http_violation.
waf.severity security_result.severity: derivato
security_result.severity_details: waf.severity
Se waf.severity non è vuoto, ne determina il valore in base agli intervalli (<=3: ALTA, >3 e <=6: MEDIA, >6 e <=8: BASSA, altrimenti: UNKNOWN_SEVERITY).security_result.severity Anche il valore waf.severity originale è mappato a security_result.severity_details.
waf_message metadata.description: waf_message Se waf.message è vuoto e waf_message non è vuoto, viene mappato a metadata.description. Se client_ip o host e fastly.server non sono vuoti, metadata.event_type viene impostato su "NETWORK_HTTP". In caso contrario, se client_ip o host non sono vuoti, metadata.event_type viene impostato su "STATUS_UPDATE". In caso contrario, viene impostato su "GENERIC_EVENT". Valore hardcoded. Valore hardcoded. Valore hardcoded.

Modifiche

2022-06-06

  • Parser appena creato.