Collecter les journaux Azure WAF
Ce document explique comment exporter les journaux du pare-feu d'application Web Azure vers Google Security Operations à l'aide d'un compte de stockage Azure. L'analyseur gère les journaux au format JSON, en les transformant en UDM. Il traite les journaux contenant un tableau records en itérant sur chaque enregistrement et en mappant des champs spécifiques sur des propriétés UDM. Si le tableau records est absent, l'analyseur gère le journal comme un seul événement, en extrayant et en mappant les champs en conséquence.
Avant de commencer
- Assurez-vous de disposer d'une instance Google SecOps.
- Assurez-vous de disposer d'un locataire Azure actif.
- Assurez-vous de disposer d'un accès privilégié à Azure.
Configurer un compte de stockage Azure
- Dans la console Azure, recherchez Comptes de stockage.
- Cliquez sur Créer.
- Spécifiez les valeurs des paramètres d'entrée suivants :
- Abonnement: sélectionnez l'abonnement.
- Groupe de ressources: sélectionnez le groupe de ressources.
- Région: sélectionnez la région.
- Performances: sélectionnez les performances (standard recommandé).
- Redondance: sélectionnez la redondance (GRS ou LRS recommandé).
- Nom du compte de stockage: saisissez un nom pour le nouveau compte de stockage.
- Cliquez sur Examiner et créer.
- Consultez la présentation du compte, puis cliquez sur Créer.
- Sur la page Vue d'ensemble du compte de stockage, sélectionnez le sous-menu Clés d'accès dans Sécurité et mise en réseau.
- Cliquez sur Afficher à côté de key1 ou key2.
- Cliquez sur Copy to clipboard (Copier dans le presse-papiers) pour copier la clé.
- Enregistrez la clé dans un emplacement sécurisé pour pouvoir l'utiliser ultérieurement.
- Sur la page Aperçu du compte de stockage, sélectionnez le sous-menu Points de terminaison dans Paramètres.
- Cliquez sur Copier dans le presse-papiers pour copier l'URL du point de terminaison du service Blob (par exemple,
https://<storageaccountname>.blob.core.windows.net
). - Enregistrez l'URL du point de terminaison dans un endroit sécurisé pour une utilisation ultérieure.
Configurer l'exportation des journaux pour les journaux Azure WAF
- Connectez-vous au portail Azure à l'aide de votre compte privilégié.
- Accédez à Règles de pare-feu d'application Web (WAF), puis sélectionnez un WAF à surveiller.
- Sélectionnez Surveillance > Paramètres de diagnostic.
- Cliquez sur + Ajouter un paramètre de diagnostic.
- Attribuez un nom descriptif au paramètre de diagnostic.
- Sélectionnez allLogs.
- Cochez la case Archiver dans un compte de stockage comme destination.
- Spécifiez l'abonnement et le compte de stockage.
- Cliquez sur Enregistrer.
Configurer un flux dans Google SecOps pour ingérer les journaux du WAF Azure
- Accédez à SIEM Settings > Feeds (Paramètres du SIEM > Flux).
- Cliquez sur Ajouter.
- Dans le champ Nom du flux, saisissez un nom pour le flux (par exemple, Journaux Azure WAF).
- Sélectionnez Microsoft Azure Blob Storage comme Type de source.
- Sélectionnez Azure WAF comme Type de journal.
- Cliquez sur Suivant.
Spécifiez les valeurs des paramètres d'entrée suivants:
- URI Azure: URL du point de terminaison de blob.
ENDPOINT_URL/BLOB_NAME
- Remplacez l'élément suivant :
ENDPOINT_URL
: URL du point de terminaison de blob (https://<storageaccountname>.blob.core.windows.net
)BLOB_NAME
: nom du blob (par exemple,<logname>-logs
)
- Remplacez l'élément suivant :
- L'URI est: sélectionnez le TYPE D'URI en fonction de la configuration du flux de journaux (Fichier unique | Répertoire | Répertoire incluant des sous-répertoires).
Options de suppression de la source: sélectionnez l'option de suppression en fonction de vos préférences.
Clé partagée: clé d'accès à Azure Blob Storage.
Espace de noms des éléments: espace de noms des éléments.
Libellés d'ingestion: libellé à appliquer aux événements de ce flux.
- URI Azure: URL du point de terminaison de blob.
Cliquez sur Suivant.
Vérifiez la configuration de votre nouveau flux dans l'écran Finaliser, puis cliquez sur Envoyer.
Tableau de mappage UDM
Champ de journal | Mappage UDM | Logique |
---|---|---|
backendPoolName |
additional.fields[?key=='backendPoolName'].value.string_value |
La valeur est extraite du champ backendPoolName du journal brut. |
backendSettingName |
additional.fields[?key=='backendSettingName'].value.string_value |
La valeur est extraite du champ backendSettingName du journal brut. |
category |
metadata.product_event_type |
La valeur est extraite du champ category du journal brut. |
EventEnqueuedUtcTime |
additional.fields[?key=='EventEnqueuedUtcTime'].value.string_value |
La valeur est extraite du champ EventEnqueuedUtcTime dans le journal brut lorsque le champ records existe. |
EventProcessedUtcTime |
additional.fields[?key=='EventProcessedUtcTime'].value.string_value |
La valeur est extraite du champ EventProcessedUtcTime dans le journal brut lorsque le champ records existe. |
operationName |
additional.fields[?key=='operationName'].value.string_value |
La valeur est extraite du champ operationName du journal brut. |
properties.action |
additional.fields[?key=='action'].value.string_value |
La valeur est extraite du champ properties.action dans le journal brut lorsque le champ records existe. |
properties.action |
security_result.action_details |
La valeur est extraite du champ properties.action dans le journal brut lorsque le champ records n'existe pas. |
properties.clientIP , properties.clientIp |
principal.asset.ip , principal.ip |
La valeur est extraite du champ properties.clientIP ou properties.clientIp du journal brut, en privilégiant clientIP . |
properties.clientPort |
principal.port |
La valeur est extraite du champ properties.clientPort du journal brut. |
properties.clientResponseTime |
principal.resource.attribute.labels[?key=='Client Response Time'].value |
La valeur est extraite du champ properties.clientResponseTime dans le journal brut lorsque le champ records n'existe pas. |
properties.details.data |
additional.fields[?key=='Properties data'].value.string_value |
La valeur est extraite du champ properties.details.data dans le journal brut lorsque le champ records existe. |
properties.details.file |
principal.process.file.full_path |
La valeur est extraite du champ properties.details.file dans le journal brut lorsque le champ records n'existe pas. |
properties.details.matches[].matchVariableName , properties.details.matches[].matchVariableValue |
additional.fields[?key.startsWith('%{idx} ')].value.string_value |
La valeur est extraite du tableau properties.details.matches dans le journal brut. Le key dans l'UDM est construit à l'aide de l'index (idx ) et de matchVariableName . Le value est extrait de matchVariableValue . |
properties.details.message |
metadata.description |
La valeur est extraite du champ properties.details.message du journal brut après suppression des barres obliques arrière et des guillemets. |
properties.details.msg |
metadata.description |
La valeur est extraite du champ properties.details.msg dans le journal brut lorsque le champ records existe. |
properties.httpMethod |
network.http.method |
La valeur est extraite du champ properties.httpMethod du journal brut. |
properties.httpStatus |
network.http.response_code |
La valeur est extraite du champ properties.httpStatus du journal brut. |
properties.httpVersion |
network.application_protocol |
Si le champ properties.httpVersion contient HTTP , la valeur HTTP est attribuée. |
properties.host , properties.hostname , properties.originalHost |
principal.asset.hostname , principal.hostname |
La valeur est extraite de l'une des valeurs properties.originalHost , properties.host ou properties.hostname , en les hiérarchisant dans cet ordre. |
properties.policyId |
security_result.detection_fields[?key=='policyId'].value |
La valeur est extraite du champ properties.policyId du journal brut. |
properties.policyMode |
security_result.detection_fields[?key=='policyMode'].value |
La valeur est extraite du champ properties.policyMode dans le journal brut lorsque le champ records existe. |
properties.policy |
additional.fields[?key=='Properties policy'].value.string_value |
La valeur est extraite du champ properties.policy dans le journal brut lorsque le champ records existe. |
properties.receivedBytes |
network.received_bytes |
La valeur est extraite du champ properties.receivedBytes du journal brut. |
properties.requestUri |
target.url |
La valeur est extraite du champ properties.requestUri du journal brut. |
properties.ruleId |
security_result.rule_id |
La valeur est extraite du champ properties.ruleId du journal brut. |
properties.ruleName |
security_result.rule_name |
La valeur est extraite du champ properties.ruleName dans le journal brut lorsque le champ records existe. |
properties.ruleName , ruleSetType |
security_result.rule_name |
La valeur est extraite du champ properties.ruleName ou, s'il est vide, du champ ruleSetType dans le journal brut lorsque le champ records n'existe pas. |
properties.ruleSetVersion |
security_result.detection_fields[?key=='ruleSetVersion'].value |
La valeur est extraite du champ properties.ruleSetVersion du journal brut. |
properties.sentBytes |
network.sent_bytes |
La valeur est extraite du champ properties.sentBytes du journal brut. |
properties.serverResponseLatency |
additional.fields[?key=='Server Response Latency'].value.string_value |
La valeur est extraite du champ properties.serverResponseLatency dans le journal brut lorsque le champ records n'existe pas. |
properties.serverRouted |
target.asset.ip , target.ip , target.port |
L'adresse IP et le port sont extraits du champ properties.serverRouted . |
properties.sslCipher |
network.tls.cipher |
La valeur est extraite du champ properties.sslCipher du journal brut. |
properties.sslClientCertificateIssuerName |
network.tls.server.certificate.issuer |
La valeur est extraite du champ properties.sslClientCertificateIssuerName du journal brut. |
properties.sslProtocol |
network.tls.version |
La valeur est extraite du champ properties.sslProtocol du journal brut. |
properties.timeTaken |
additional.fields[?key=='Properties Timetaken'].value.string_value |
La valeur est extraite du champ properties.timeTaken dans le journal brut lorsque le champ records n'existe pas. |
properties.trackingReference |
additional.fields[?key=='trackingReference'].value.string_value |
La valeur est extraite du champ properties.trackingReference dans le journal brut lorsque le champ records existe. |
properties.transactionId |
network.session_id |
La valeur est extraite du champ properties.transactionId du journal brut. |
properties.userAgent |
network.http.user_agent |
La valeur est extraite du champ properties.userAgent du journal brut. |
properties.WAFEvaluationTime |
additional.fields[?key=='Properties WAFEvaluationTime'].value.string_value |
La valeur est extraite du champ properties.WAFEvaluationTime dans le journal brut lorsque le champ records n'existe pas. |
properties.WAFMode |
additional.fields[?key=='Properties WAFMode'].value.string_value |
La valeur est extraite du champ properties.WAFMode dans le journal brut lorsque le champ records n'existe pas. |
rec.category |
metadata.product_event_type |
La valeur est extraite du champ rec.category dans le journal brut lorsque le champ records existe. |
rec.operationName |
additional.fields[?key=='operationName'].value.string_value |
La valeur est extraite du champ rec.operationName dans le journal brut lorsque le champ records existe. |
rec.properties.clientIP , rec.properties.clientIp |
principal.asset.ip , principal.ip |
La valeur est extraite du champ rec.properties.clientIP ou rec.properties.clientIp du journal brut, en privilégiant clientIP lorsque le champ records existe. |
rec.properties.clientPort |
principal.port |
La valeur est extraite du champ rec.properties.clientPort dans le journal brut lorsque le champ records existe. |
rec.properties.host |
principal.asset.hostname , principal.hostname |
La valeur est extraite du champ rec.properties.host dans le journal brut lorsque le champ records existe. |
rec.properties.policy |
additional.fields[?key=='Properties policy'].value.string_value |
La valeur est extraite du champ rec.properties.policy dans le journal brut lorsque le champ records existe. |
rec.properties.requestUri |
target.url |
La valeur est extraite du champ rec.properties.requestUri dans le journal brut lorsque le champ records existe. |
rec.properties.ruleName |
security_result.rule_name |
La valeur est extraite du champ rec.properties.ruleName dans le journal brut lorsque le champ records existe. |
rec.properties.trackingReference |
additional.fields[?key=='trackingReference'].value.string_value |
La valeur est extraite du champ rec.properties.trackingReference dans le journal brut lorsque le champ records existe. |
rec.resourceId |
target.resource.id |
La valeur est extraite du champ rec.resourceId dans le journal brut lorsque le champ records existe. |
rec.time |
metadata.event_timestamp |
La valeur est extraite du champ rec.time dans le journal brut lorsque le champ records existe. |
resourceId |
target.resource.id |
La valeur est extraite du champ resourceId dans le journal brut lorsque le champ records n'existe pas. |
timeStamp |
metadata.event_timestamp |
La valeur est extraite du champ timeStamp dans le journal brut lorsque le champ records n'existe pas. |
N/A | metadata.event_type |
La valeur est définie sur NETWORK_CONNECTION si le principal (nom d'hôte ou adresse IP du client) et l'adresse IP de destination sont tous deux présents. Il est défini sur STATUS_UPDATE si un principal est présent, mais que l'adresse IP de destination est manquante. Sinon, la valeur par défaut est GENERIC_EVENT ou la valeur du champ event_type . |
N/A | metadata.log_type |
La valeur est codée en dur sur AZURE_WAF . |
N/A | metadata.product_name |
La valeur est codée en dur sur Azure WAF Logs . |
N/A | metadata.vendor_name |
La valeur est codée en dur sur Microsoft . |
N/A | security_result.action |
La valeur est définie sur ALLOW si properties.action est Matched , sur BLOCK si properties.action est Block . |
Modifications
2024-04-07
Amélioration :
- Mappage de
rec.properties.clientIp
surprincipal.ip
. - Définition de
rec_properties_trackingReference
,rec_properties_host
,rec_properties_policyMode
,rec_properties_ruleName
,rec_properties_policy
,rec_properties_details_msg
,rec_properties_clientIP
etrec_time
dans les données d'état.
2023-07-14
Amélioration :
- Ajout d'une boucle
for
pour gérer les journaux JSON.
2023-02-28
Amélioration :
- Mappage de
properties.ruleName
sursecurity_result.rule_name
. - Mappage de
properties.action
sursecurity_result.action
. - Ajout d'une vérification on_error pour
properties.clientPort
,properties.httpStatus
,properties.receivedBytes
,properties.sentBytes
,properties.clientResponseTime
etproperties.timeTaken
.
2022-10-22
- Analyseur nouvellement créé
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.