Raccogliere i log di Azure WAF
Questo documento spiega come esportare i log del web application firewall (WAF) di Azure in Google Security Operations utilizzando un account di archiviazione Azure. Il parser gestisce i log in formato JSON, trasformandoli in UDM. Elabora i log contenenti un array di record eseguendo l'iterazione di ogni record e mappando campi specifici alle proprietà UDM. Se l'array records non è presente, l'analizzatore gestisce il log come un singolo evento, estraendo e mappando i campi di conseguenza.
Prima di iniziare
- Assicurati di avere un'istanza Google SecOps.
- Assicurati di avere un tenant Azure attivo.
- Assicurati di disporre dell'accesso privilegiato ad Azure.
Configura l'account di archiviazione Azure
- Nella console di Azure, cerca Account di archiviazione.
- Fai clic su Crea.
- Specifica i valori per i seguenti parametri di input:
- Abbonamento: seleziona l'abbonamento.
- Gruppo di risorse: seleziona il gruppo di risorse.
- Regione: seleziona la regione.
- Prestazioni: seleziona il rendimento (consigliato standard).
- Redundanza: seleziona la ridondanza (consigliata GRS o LRS).
- Nome account di archiviazione: inserisci un nome per il nuovo account di archiviazione.
- Fai clic su Review + create (Rivedi e crea).
- Esamina la panoramica dell'account e fai clic su Crea.
- Nella pagina Panoramica dell'account di archiviazione, seleziona il sottomenu Chiavi di accesso in Sicurezza + reti.
- Fai clic su Mostra accanto a chiave1 o chiave2.
- Fai clic su Copia negli appunti per copiare la chiave.
- Salva la chiave in un luogo sicuro per utilizzarla in un secondo momento.
- Nella pagina Panoramica dell'account di archiviazione, seleziona il sottomenu Endpoint in Impostazioni.
- Fai clic su Copia negli appunti per copiare l'URL dell'endpoint del servizio Blob, ad esempio
https://<storageaccountname>.blob.core.windows.net
. - Salva l'URL dell'endpoint in un luogo sicuro per utilizzarlo in un secondo momento.
Configurare l'esportazione dei log per i log di Azure WAF
- Accedi al portale di Azure utilizzando il tuo account con privilegi.
- Vai a Regole del web application firewall (WAF) e seleziona un WAF da monitorare.
- Seleziona Monitoraggio > Impostazioni di diagnostica.
- Fai clic su + Aggiungi impostazione di diagnostica.
- Inserisci un nome descrittivo per l'impostazione di diagnostica.
- Seleziona allLogs.
- Seleziona la casella di controllo Archivia in un account di archiviazione come destinazione.
- Specifica l'abbonamento e l'account di archiviazione.
- Fai clic su Salva.
Configura un feed in Google SecOps per importare i log di Azure WAF
- Vai a Impostazioni SIEM > Feed.
- Fai clic su Aggiungi nuovo.
- Nel campo Nome feed, inserisci un nome per il feed, ad esempio Log Azure WAF.
- Seleziona Microsoft Azure Blob Storage come Tipo di origine.
- Seleziona Azure WAF come Tipo di log.
- Fai clic su Avanti.
Specifica i valori per i seguenti parametri di input:
- URI Azure: l'URL dell'endpoint del blob.
ENDPOINT_URL/BLOB_NAME
- Sostituisci quanto segue:
ENDPOINT_URL
: l'URL dell'endpoint blob (https://<storageaccountname>.blob.core.windows.net
)BLOB_NAME
: il nome del blob (ad esempio<logname>-logs
)
- Sostituisci quanto segue:
- L'URI è un: seleziona il TIPO DI URI in base alla configurazione dello stream di log (File singolo | Directory | Directory che include sottodirectory).
Opzioni di eliminazione dell'origine: seleziona l'opzione di eliminazione in base alle tue preferenze.
Chiave condivisa: la chiave di accesso ad Azure Blob Storage.
Spazio dei nomi degli asset: lo spazio dei nomi degli asset.
Etichette di importazione: l'etichetta da applicare agli eventi di questo feed.
- URI Azure: l'URL dell'endpoint del blob.
Fai clic su Avanti.
Rivedi la configurazione del nuovo feed nella schermata Concludi e poi fai clic su Invia.
Tabella di mappatura UDM
Campo log | Mappatura UDM | Logica |
---|---|---|
backendPoolName |
additional.fields[?key=='backendPoolName'].value.string_value |
Il valore viene preso dal campo backendPoolName nel log non elaborato. |
backendSettingName |
additional.fields[?key=='backendSettingName'].value.string_value |
Il valore viene preso dal campo backendSettingName nel log non elaborato. |
category |
metadata.product_event_type |
Il valore viene preso dal campo category nel log non elaborato. |
EventEnqueuedUtcTime |
additional.fields[?key=='EventEnqueuedUtcTime'].value.string_value |
Il valore viene preso dal campo EventEnqueuedUtcTime nel log non elaborato se esiste il campo records . |
EventProcessedUtcTime |
additional.fields[?key=='EventProcessedUtcTime'].value.string_value |
Il valore viene preso dal campo EventProcessedUtcTime nel log non elaborato se esiste il campo records . |
operationName |
additional.fields[?key=='operationName'].value.string_value |
Il valore viene preso dal campo operationName nel log non elaborato. |
properties.action |
additional.fields[?key=='action'].value.string_value |
Il valore viene preso dal campo properties.action nel log non elaborato se esiste il campo records . |
properties.action |
security_result.action_details |
Il valore viene preso dal campo properties.action nel log non elaborato quando il campo records non esiste. |
properties.clientIP , properties.clientIp |
principal.asset.ip , principal.ip |
Il valore viene preso dal campo properties.clientIP o properties.clientIp nel log non elaborato, dando la priorità a clientIP . |
properties.clientPort |
principal.port |
Il valore viene preso dal campo properties.clientPort nel log non elaborato. |
properties.clientResponseTime |
principal.resource.attribute.labels[?key=='Client Response Time'].value |
Il valore viene preso dal campo properties.clientResponseTime nel log non elaborato quando il campo records non esiste. |
properties.details.data |
additional.fields[?key=='Properties data'].value.string_value |
Il valore viene preso dal campo properties.details.data nel log non elaborato se esiste il campo records . |
properties.details.file |
principal.process.file.full_path |
Il valore viene preso dal campo properties.details.file nel log non elaborato quando il campo records non esiste. |
properties.details.matches[].matchVariableName , properties.details.matches[].matchVariableValue |
additional.fields[?key.startsWith('%{idx} ')].value.string_value |
Il valore viene preso dall'array properties.details.matches nel log non elaborato. Il key nell'UDM viene creato utilizzando l'indice (idx ) e matchVariableName . value è tratto da matchVariableValue . |
properties.details.message |
metadata.description |
Il valore viene preso dal campo properties.details.message nel log non elaborato dopo aver rimosso le barre diagonali e le virgolette. |
properties.details.msg |
metadata.description |
Il valore viene preso dal campo properties.details.msg nel log non elaborato se esiste il campo records . |
properties.httpMethod |
network.http.method |
Il valore viene preso dal campo properties.httpMethod nel log non elaborato. |
properties.httpStatus |
network.http.response_code |
Il valore viene preso dal campo properties.httpStatus nel log non elaborato. |
properties.httpVersion |
network.application_protocol |
Se il campo properties.httpVersion contiene HTTP , viene assegnato il valore HTTP . |
properties.host , properties.hostname , properties.originalHost |
principal.asset.hostname , principal.hostname |
Il valore viene preso da uno dei valori properties.originalHost , properties.host o properties.hostname , dando loro la priorità in questo ordine. |
properties.policyId |
security_result.detection_fields[?key=='policyId'].value |
Il valore viene preso dal campo properties.policyId nel log non elaborato. |
properties.policyMode |
security_result.detection_fields[?key=='policyMode'].value |
Il valore viene preso dal campo properties.policyMode nel log non elaborato se esiste il campo records . |
properties.policy |
additional.fields[?key=='Properties policy'].value.string_value |
Il valore viene preso dal campo properties.policy nel log non elaborato se esiste il campo records . |
properties.receivedBytes |
network.received_bytes |
Il valore viene preso dal campo properties.receivedBytes nel log non elaborato. |
properties.requestUri |
target.url |
Il valore viene preso dal campo properties.requestUri nel log non elaborato. |
properties.ruleId |
security_result.rule_id |
Il valore viene preso dal campo properties.ruleId nel log non elaborato. |
properties.ruleName |
security_result.rule_name |
Il valore viene preso dal campo properties.ruleName nel log non elaborato se esiste il campo records . |
properties.ruleName , ruleSetType |
security_result.rule_name |
Il valore viene preso dal campo properties.ruleName o, se vuoto, dal campo ruleSetType nel log non elaborato quando il campo records non esiste. |
properties.ruleSetVersion |
security_result.detection_fields[?key=='ruleSetVersion'].value |
Il valore viene preso dal campo properties.ruleSetVersion nel log non elaborato. |
properties.sentBytes |
network.sent_bytes |
Il valore viene preso dal campo properties.sentBytes nel log non elaborato. |
properties.serverResponseLatency |
additional.fields[?key=='Server Response Latency'].value.string_value |
Il valore viene preso dal campo properties.serverResponseLatency nel log non elaborato quando il campo records non esiste. |
properties.serverRouted |
target.asset.ip , target.ip , target.port |
L'IP e la porta vengono estratti dal campo properties.serverRouted . |
properties.sslCipher |
network.tls.cipher |
Il valore viene preso dal campo properties.sslCipher nel log non elaborato. |
properties.sslClientCertificateIssuerName |
network.tls.server.certificate.issuer |
Il valore viene preso dal campo properties.sslClientCertificateIssuerName nel log non elaborato. |
properties.sslProtocol |
network.tls.version |
Il valore viene preso dal campo properties.sslProtocol nel log non elaborato. |
properties.timeTaken |
additional.fields[?key=='Properties Timetaken'].value.string_value |
Il valore viene preso dal campo properties.timeTaken nel log non elaborato quando il campo records non esiste. |
properties.trackingReference |
additional.fields[?key=='trackingReference'].value.string_value |
Il valore viene preso dal campo properties.trackingReference nel log non elaborato se esiste il campo records . |
properties.transactionId |
network.session_id |
Il valore viene preso dal campo properties.transactionId nel log non elaborato. |
properties.userAgent |
network.http.user_agent |
Il valore viene preso dal campo properties.userAgent nel log non elaborato. |
properties.WAFEvaluationTime |
additional.fields[?key=='Properties WAFEvaluationTime'].value.string_value |
Il valore viene preso dal campo properties.WAFEvaluationTime nel log non elaborato quando il campo records non esiste. |
properties.WAFMode |
additional.fields[?key=='Properties WAFMode'].value.string_value |
Il valore viene preso dal campo properties.WAFMode nel log non elaborato quando il campo records non esiste. |
rec.category |
metadata.product_event_type |
Il valore viene preso dal campo rec.category nel log non elaborato se esiste il campo records . |
rec.operationName |
additional.fields[?key=='operationName'].value.string_value |
Il valore viene preso dal campo rec.operationName nel log non elaborato se esiste il campo records . |
rec.properties.clientIP , rec.properties.clientIp |
principal.asset.ip , principal.ip |
Il valore viene preso dal campo rec.properties.clientIP o rec.properties.clientIp nel log non elaborato, dando la priorità a clientIP se esiste il campo records . |
rec.properties.clientPort |
principal.port |
Il valore viene preso dal campo rec.properties.clientPort nel log non elaborato se esiste il campo records . |
rec.properties.host |
principal.asset.hostname , principal.hostname |
Il valore viene preso dal campo rec.properties.host nel log non elaborato se esiste il campo records . |
rec.properties.policy |
additional.fields[?key=='Properties policy'].value.string_value |
Il valore viene preso dal campo rec.properties.policy nel log non elaborato se esiste il campo records . |
rec.properties.requestUri |
target.url |
Il valore viene preso dal campo rec.properties.requestUri nel log non elaborato se esiste il campo records . |
rec.properties.ruleName |
security_result.rule_name |
Il valore viene preso dal campo rec.properties.ruleName nel log non elaborato se esiste il campo records . |
rec.properties.trackingReference |
additional.fields[?key=='trackingReference'].value.string_value |
Il valore viene preso dal campo rec.properties.trackingReference nel log non elaborato se esiste il campo records . |
rec.resourceId |
target.resource.id |
Il valore viene preso dal campo rec.resourceId nel log non elaborato se esiste il campo records . |
rec.time |
metadata.event_timestamp |
Il valore viene preso dal campo rec.time nel log non elaborato se esiste il campo records . |
resourceId |
target.resource.id |
Il valore viene preso dal campo resourceId nel log non elaborato quando il campo records non esiste. |
timeStamp |
metadata.event_timestamp |
Il valore viene preso dal campo timeStamp nel log non elaborato quando il campo records non esiste. |
N/D | metadata.event_type |
Il valore è impostato su NETWORK_CONNECTION se sono presenti sia il principale (nome host o indirizzo IP del client) sia l'indirizzo IP di destinazione. È impostato su STATUS_UPDATE se è presente un'entità, ma manca l'IP di destinazione. In caso contrario, il valore predefinito è GENERIC_EVENT o il valore del campo event_type . |
N/D | metadata.log_type |
Il valore è hardcoded su AZURE_WAF . |
N/D | metadata.product_name |
Il valore è hardcoded su Azure WAF Logs . |
N/D | metadata.vendor_name |
Il valore è hardcoded su Microsoft . |
N/D | security_result.action |
Il valore è impostato su ALLOW se properties.action è Matched , BLOCK se properties.action è Block . |
Modifiche
2024-04-07
Miglioramento:
rec.properties.clientIp
è stato mappato aprincipal.ip
.- Sono stati definiti
rec_properties_trackingReference
,rec_properties_host
,rec_properties_policyMode
,rec_properties_ruleName
,rec_properties_policy
,rec_properties_details_msg
,rec_properties_clientIP
erec_time
nei dati dello stato.
2023-07-14
Miglioramento:
- È stato aggiunto un ciclo
for
per gestire i log JSON.
2023-02-28
Miglioramento:
properties.ruleName
è stato mappato asecurity_result.rule_name
.properties.action
è stato mappato asecurity_result.action
.- È stato aggiunto il controllo on_error per
properties.clientPort
,properties.httpStatus
,properties.receivedBytes
,properties.sentBytes
,properties.clientResponseTime
,properties.timeTaken
.
2022-10-22
- Analizzatore appena creato
Hai bisogno di ulteriore assistenza? Ricevi risposte dai membri della community e dai professionisti di Google SecOps.