Collecter les journaux AWS WAF
Ce document explique comment collecter les journaux AWS Web Application Firewall (WAF) en configurant un flux Google Security Operations. L'analyseur transforme les journaux bruts au format JSON en un format structuré conforme à l'UDM Google SecOps. Il extrait des champs tels que les adresses IP, les URL, les user-agents et les détails des règles de sécurité, et les mappe aux champs UDM correspondants pour une représentation et une analyse cohérentes.
Avant de commencer
*Assurez-vous de remplir les conditions préalables suivantes :
- Instance Google SecOps
- Accès privilégié à AWS
Configurer le bucket Amazon S3
- Créez un bucket Amazon S3 en suivant ce guide de l'utilisateur : Créer un bucket.
- Enregistrez le nom et la région du bucket pour une utilisation ultérieure.
- Créez un utilisateur en suivant ce guide : Créer un utilisateur IAM.
- Sélectionnez l'utilisateur créé.
- Sélectionnez l'onglet Informations d'identification de sécurité.
- Cliquez sur Créer une clé d'accès dans la section Clés d'accès.
- Sélectionnez Service tiers comme Cas d'utilisation.
- Cliquez sur Suivant.
- Facultatif : ajoutez une balise de description.
- Cliquez sur Créer une clé d'accès.
- Cliquez sur Télécharger le fichier CSV pour enregistrer la clé d'accès et la clé d'accès secrète pour une utilisation ultérieure.
- Cliquez sur OK.
- Sélectionnez l'onglet Autorisations.
- Cliquez sur Ajouter des autorisations dans la section Règles d'autorisation.
- Sélectionnez Ajouter des autorisations.
- Sélectionnez Joindre directement des règles.
- Recherchez et sélectionnez la règle AmazonS3FullAccess.
- Cliquez sur Suivant.
- Cliquez sur Ajouter des autorisations.
Créer une LCA (liste de contrôle d'accès) WAF Web
Si vous n'avez pas encore configuré AWS WAF, vous devrez créer une LCA (liste de contrôle d'accès) WAF pour le Web. Si vous disposez déjà d'une configuration, vous pouvez passer à la procédure suivante.
- Dans la console AWS, recherchez et sélectionnez AWS WAF & Shield.
- Cliquez sur Create web ACL (Créer une ACL Web).
- Définissez les paramètres suivants :
- Nom : donnez un nom à la LCA (par exemple,
my-waf-web-acl
). - Région : choisissez la région dans laquelle vous souhaitez appliquer le WAF.
- Métriques CloudWatch : activez la collecte de métriques pour suivre l'activité et les règles déclenchées.
- Nom : donnez un nom à la LCA (par exemple,
- Une fois la liste de contrôle d'accès Web créée, sélectionnez celle pour laquelle vous souhaitez activer la journalisation.
Configurer la journalisation AWS WAF
- Dans la console AWS WAF, accédez à l'onglet Logging (Journalisation) de votre ACL Web.
- Cliquez sur Activer la journalisation.
- Sélectionnez Amazon S3 comme destination pour vos journaux.
- Choisissez le bucket S3 créé précédemment pour stocker les journaux.
- Facultatif : configurez un préfixe de journal pour organiser les journaux (par exemple,
waf-logs/
). - Cliquez sur Enregistrer.
Vérifier les autorisations pour le bucket S3
Assurez-vous que le bucket S3 dispose des autorisations appropriées pour qu'AWS WAF puisse y écrire des journaux.
- Accédez à la console S3.
- Sélectionnez le bucket dans lequel les journaux seront stockés.
Dans l'onglet Autorisations, ajoutez la stratégie de bucket suivante pour permettre à AWS WAF d'écrire des journaux :
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "wafv2.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::your-log-bucket-name/*" } ] }
- Cliquez sur Enregistrer.
Configurer des flux
Il existe deux points d'entrée différents pour configurer les flux dans la plate-forme Google SecOps :
- Paramètres SIEM> Flux > Ajouter un flux
- Plate-forme de contenu> Packs de contenu> Premiers pas
Configurer le flux AWS WAF
- Cliquez sur le pack Amazon Cloud Platform.
- Recherchez le type de journal AWS WAF.
Spécifiez les valeurs des champs suivants.
- Type de source : Amazon SQS V2
- Nom de la file d'attente : nom de la file d'attente SQS à partir de laquelle lire les données
- URI S3 : URI du bucket.
s3://your-log-bucket-name/
- Remplacez
your-log-bucket-name
par le nom réel de votre bucket S3.
- Remplacez
Options de suppression de la source : sélectionnez l'option de suppression en fonction de vos préférences d'ingestion.
Âge maximal des fichiers : incluez les fichiers modifiés au cours des derniers jours. La valeur par défaut est de 180 jours.
ID de clé d'accès à la file d'attente SQS : clé d'accès au compte, qui est une chaîne alphanumérique de 20 caractères.
Clé d'accès secrète à la file d'attente SQS : clé d'accès au compte, qui est une chaîne alphanumérique de 40 caractères.
Options avancées
- Nom du flux : valeur préremplie qui identifie le flux.
- Espace de noms de l'élément : espace de noms associé au flux.
- Libellés d'ingestion : libellés appliqués à tous les événements de ce flux.
Cliquez sur Créer un flux.
Pour en savoir plus sur la configuration de plusieurs flux pour différents types de journaux dans cette famille de produits, consultez Configurer des flux par produit.
Table de mappage UDM
Champ du journal | Mappage UDM | Logique |
---|---|---|
action | security_result.action | Si l'action est ALLOW, définissez security_result.action sur ALLOW et security_result.severity sur INFORMATIONAL. Si l'action est BLOCK, définissez security_result.action sur BLOCK. Si l'action est CAPTCHA et que captchaResponse.responseCode est défini sur 405, définissez security_result.action sur BLOCK et security_result.action_details sur "CAPTCHA {captchaResponse.failureReason}". |
captchaResponse.failureReason | security_result.action_details | Utilisé conjointement avec action et captchaResponse.responseCode pour déterminer security_result.action_details. |
captchaResponse.responseCode | security_result.action_details | Utilisé conjointement avec action et captchaResponse.failureReason pour déterminer security_result.action_details. |
httpRequest.clientIp | principal.ip, principal.asset.ip | Directement mappé à principal.ip et principal.asset.ip. |
httpRequest.headers | target.hostname, target.asset.hostname, network.http.user_agent, network.http.parsed_user_agent, network.http.referral_url, target.location.country_or_region, target.resource.attribute.labels, target.user.userid | Parcourt chaque en-tête dans httpRequest.headers. Si le nom de l'en-tête est "host" ou "Host", la valeur est mappée sur target.hostname et target.asset.hostname. Si le nom de l'en-tête est "User-Agent" ou "user-agent", la valeur est mappée sur network.http.user_agent et analysée dans network.http.parsed_user_agent. Si le nom de l'en-tête est "Referer" ou "referer", la valeur est mappée sur network.http.referral_url. Si le nom de l'en-tête est "(?i)time-zone", la valeur est mappée sur target.location.country_or_region. Si le nom de l'en-tête est "authorization", la valeur est décodée, et le nom d'utilisateur est extrait et mappé sur target.user.userid. Tous les autres en-têtes sont ajoutés sous forme de paires clé-valeur à target.resource.attribute.labels. |
httpRequest.httpMethod | network.http.method | Directement mappé à network.http.method. |
httpRequest.requestId | network.session_id | Mappé directement sur network.session_id. |
httpRequest.uri | target.url | Directement mappé à target.url. |
httpSourceId | target.resource.name | Directement mappé à target.resource.name. |
httpSourceName | metadata.product_event_type | Mappé directement sur metadata.product_event_type. |
labels | security_result.rule_labels | Itère sur chaque libellé dans "labels". Si le nom du libellé n'est pas vide, il est ajouté en tant que paire clé/valeur à security_result.rule_labels. |
nonTerminatingMatchingRules | security_result.action_details, security_result.rule_labels | Itère sur chaque règle dans nonTerminatingMatchingRules. Si l'action est ALLOW et que l'action de la règle est CAPTCHA, définissez security_result.action_details sur "CAPTCHA SUCCESSFUL" et ajoutez l'ID de la règle à security_result.rule_labels avec la clé "nonTerminatingCaptchaRuleName". Si l'action est BLOCK ou ALLOW et que l'action de la règle est COUNT, définissez security_result.action_details sur "COUNT RULE" et ajoutez l'ID de la règle à security_result.rule_labels avec la clé "nonTerminatingCountRuleName". Si l'action est BLOCK ou ALLOW et que l'action de la règle est CHALLENGE, définissez security_result.action_details sur "COUNT RULE" et ajoutez l'ID de la règle à security_result.rule_labels avec la clé "nonTerminatingChallengeRuleName". |
rateBasedRuleList | security_result.rule_id, security_result.rule_name, security_result.description | Si terminatingRuleType est défini sur "RATE_BASED", il parcourt chaque règle de rateBasedRuleList. Si terminatingRuleId correspond au nom de la règle, l'ID, le nom et la description de la règle sont respectivement mappés à security_result.rule_id, security_result.rule_name et security_result.description. |
responseCodeSent | network.http.response_code | Directement mappé à network.http.response_code et converti en entier. |
ruleGroupList | intermediary.labels, security_result.rule_id, security_result.rule_name, security_result.description, security_result.detection_fields | Itère sur chaque groupe de règles de ruleGroupList. L'ID du groupe de règles est ajouté en tant que paire clé-valeur à intermediary.labels. Si terminatingRuleType est "MANAGED_RULE_GROUP" et que terminatingRuleId correspond à l'ID du groupe de règles, l'ID, le nom et la description de la règle sont mappés respectivement à security_result.rule_id, security_result.rule_name et security_result.description. Si terminatingRuleType est défini sur "GROUP", l'ID de la règle de fin est extrait et mappé sur security_result.rule_name et security_result.description. L'ID du groupe de règles de fin est ajouté à security_result.rule_labels avec la clé "terminatingRuleGroupName". Si terminatingRuleType est défini sur "REGULAR", l'action de la règle de fin est extraite et ajoutée aux champs security_result.detectionavec la clé "terminatingRuleAction{index}". |
terminatingRuleId | security_result.rule_id, security_result.rule_name, security_result.description | Si terminatingRuleType est défini sur "RATE_BASED", "MANAGED_RULE_GROUP" ou "REGULAR", terminatingRuleId est mappé sur security_result.rule_id et security_result.rule_name, et utilisé pour construire security_result.description. |
terminatingRuleMatchDetails | security_result.description, security_result.category_details, security_result.detection_fields | Itère sur chaque correspondance dans terminatingRuleMatchDetails. Définit security_result.description sur "Règle de clôture". Si le type de condition n'est pas vide, il est ajouté à security_result.category_details. Si l'emplacement n'est pas vide, il est ajouté à security_result.detection_fields avec la clé "location". Chaque élément de données correspondant est ajouté à security_result.detection_fields avec la clé "matchedData". |
terminatingRuleType | security_result.rule_type | Mappé directement à security_result.rule_type. |
timestamp | metadata.event_timestamp | Converti en code temporel et mappé à metadata.event_timestamp. |
webaclId | intermediary.resource.name | Directement mappé à intermediary.resource.name. |
metadata.vendor_name | Définissez-le sur "AMAZON". | |
metadata.product_name | Définissez la valeur sur "Pare-feu d'application Web AWS". | |
metadata.log_type | Défini sur "AWS_WAF". | |
network.application_protocol | Définissez-le sur "HTTP". | |
metadata.event_type | Définissez sur "NETWORK_HTTP" si httpRequest.headers contient un en-tête "host" ou "Host". Sinon, définissez-le sur "STATUS_UPDATE". |
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.