Passer au contenu

Comment analyser les journaux AWS WAF dans CloudWatch ?

Lecture de 6 minute(s)
0

Je souhaite analyser et filtrer mes journaux AWS WAF que je stocke dans Amazon CloudWatch.

Résolution

Pour analyser et filtrer des demandes de journaux AWS WAF spécifiques dans CloudWatch, utilisez CloudWatch Logs Insights ou le générateur de requête CloudWatch.

CloudWatch Log Insights

Vous pouvez utiliser CloudWatch Log Insights depuis la console CloudWatch ou depuis l'onglet Log Insights dans AWS WAF.

AWS WAF

Procédez comme suit :

  1. Ouvrez la console AWS WAF.
  2. Dans le volet de navigation, sélectionnez AWS WAF.
  3. Choisissez Packs de ressources et de protection.
  4. Sélectionnez votre pack de protection.
  5. Choisissez Afficher le tableau de bord.
  6. Développez Explorateur de journaux en bas de la page.
  7. Choisissez Afficher dans CloudWatch.
  8. Dans l'Éditeur de requête, saisissez votre requête. Utilisez la syntaxe de requête pour concevoir vos requêtes. Vous pouvez également sélectionner des requêtes dans la liste des Requêtes les plus fréquemment utilisées.
  9. Sélectionnez Exécuter la requête.

CloudWatch

Procédez comme suit :

  1. Ouvrez la console CloudWatch.
  2. Dans le volet de navigation, sélectionnez Journaux.
  3. Choisissez Log Insights.
  4. Sous Log Insights, ouvrez la liste déroulante Critères de sélection.
  5. Sélectionnez un ou plusieurs groupes de journaux à interroger. Vous pouvez également sélectionner Parcourir les groupes de journaux, puis sélectionner vos groupes de journaux.
  6. (Facultatif) Choisissez une période pour votre requête.
  7. Utilisez la syntaxe de requête pour concevoir vos requêtes.
  8. Pour consulter vos résultats, sélectionnez Exécuter la requête.

Générateur de requête CloudWatch

Pour utiliser l'IA générative afin d'analyser vos journaux d'accès, exécutez le générateur de requête dans CloudWatch.

Exemples de requêtes pour rechercher vos données

Pour filtrer des informations spécifiques avec CloudWatch Logs Insights, utilisez les exemples de requêtes suivants.

Principales adresses IP client

Pour compter les adresses IP des principaux clients qui accèdent à vos journaux, exécutez la requête suivante :

fields httpRequest.clientIp| stats count(*) as requestCount by httpRequest.clientIp
| sort requestCount desc

Principaux pays

Pour compter les principaux pays qui accèdent à vos journaux, exécutez la requête suivante :

stats count(*) as RequestCount by httpRequest.country as Country| sort RequestCount desc

Principaux hôtes

Pour compter les meilleurs hôtes qui accèdent à vos journaux, exécutez la requête suivante :

parse @message /\{"name":"[Hh]ost\",\"value":\"(?[^"}]*)/|stats count(*) as RequestCount by Host
| sort RequestCount desc

Principales méthodes

Pour répertorier les principales méthodes qui accèdent à vos journaux, exécutez la requête suivante :

stats count(*)as RequestCount by httpRequest.httpMethod as Method| sort RequestCount desc

Principaux agents utilisateur

Pour compter les principaux agents utilisateur qui accèdent à vos journaux, exécutez la requête suivante :

parse @message /\{"name":"[Uu]ser\-[Aa]gent\",\"value\"\:\"(?[^"}]*)/| stats count(*) as RequestCount by UserAgent
| sort RequestCount desc

Principales règles de résiliation

Pour comptabiliser les principales règles de résiliation dans vos journaux, exécutez la requête suivante :

stats count(*) as RequestCount by terminatingRuleId| sort RequestCount desc

Filtrer en fonction des requêtes bloquées

Pour filtrer toutes les requêtes bloquées, ainsi que la règle de résiliation, le chemin URI et l’adresse IP client respectifs, exécutez la requête suivante :

fields @timestamp, httpRequest.clientIp as ClientIP, httpRequest.uri as URI, terminatingRuleId as rule| filter action = "BLOCK"
| sort @timestamp desc

Filtrer par hôte

Pour filtrer vos journaux en fonction d'un hôte spécifique, exécutez la requête suivante :

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.uri as URI| parse @message /\{"name":"[Hh]ost\",\"value":\"(?[^"}]*)/
| filter Host = "www.example.com"

Remarque : Remplacez www.example.com par le nom de votre hôte.

Filtrer en fonction d’une chaîne spécifique

Pour filtrer vos journaux selon une chaîne spécifique, exécutez la requête suivante :

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.httpMethod as Method,httpRequest.uri as URI| parse @message /\{"name":"[Hh]ost\",\"value":\"(?[^"}])/
| parse @message /\{"name":"[Uu]ser\-[Aa]gent\",\"value\"\:\"(?[^"}])/
| filter @message like "{jndi:ldap"  
| sort action, URI desc

Remarque : Remplacez {jndi:ldap par votre chaîne.

Filtrer en fonction de requêtes POST

Pour filtrer les requêtes POST, exécutez la requête suivante :

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.httpMethod as Method, httpRequest.uri as URI| parse @message /\{"name":"[Uu]ser\-[Aa]gent\",\"value\"\:\"(?[^"}]*)/| parse @message /\{"name":"[Hh]ost\",\"value":\"(?[^"}]*)/
| filter httpRequest.httpMethod ="POST"
| display Rule, action, Country, ClientIP, Method, URI, Host, UserAgent
| sort Rule, action desc

Filtrer par pays

Pour filtrer les requêtes qui ne proviennent pas d'un pays spécifique, exécutez la requête suivante :

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.uri as URI| parse @message /\{"name":"[Hh]ost\",\"value":\"(?[^"}]*)/
| parse @message /\{"name":"[Uu]ser\-[Aa]gent\",\"value\"\:\"(?[^"}]*)/
| filter Country != "US"
| sort Country, action desc

Remarque : Remplacez USA par le code pays que vous souhaitez filtrer.

Filtrer les requêtes bloquées en fonction de règles fréquentielles

Pour filtrer vos journaux bloqués en fonction d’une règle fréquentielle, exécutez la requête suivante :

fields @timestamp, httpRequest.clientIp as ClientIP, httpRequest.uri as URI, terminatingRuleId as rule, httpRequest.country as Country| filter action = "BLOCK"
| filter terminatingRuleType = "RATE_BASED"
| sort @timestamp desc

Scripts inter-site (XSS) ou injection SQL

Pour trouver des modèles qui provoquent une injection XSS ou SQL dans la règle de résiliation de règles personnalisées ou de groupes de règles gérées par AWS, exécutez la requête suivante.

fields @timestamp| parse @message ',"terminatingRuleMatchDetails":[*],' as terminatingRuleMatchData
| filter (terminatingRuleMatchData like /XSS/ or terminatingRuleMatchData like /SQL/)
| display @timestamp, httpRequest.clientIp, httpRequest.country, terminatingRuleMatchData, httpRequest.requestId

La requête affiche les entrées avec un horodatage, l'adresse IP du client, le pays d'origine, les détails de la correspondance et l'ID de la requête.

Filtrer en fonction de requêtes comptabilisées par une règle spécifique dans un groupe de règles

Pour filtrer les entrées de journal des requêtes qu'une règle spécifique d'un groupe de règles comptabilise et résilie par défaut, exécutez la requête suivante :

fields @timestamp| filter (@message like 'excludedRules":[{"exclusionType":"EXCLUDED_AS_COUNT","ruleId":"NoUserAgent_HEADER"}]}' and @message like 'terminatingRuleId":"Default_Action"')
| parse @message '"ruleId":*}]}' as ruleMatchDetails
| display @timestamp, httpRequest.clientIp, httpRequest.country, ruleMatchDetails, httpRequest.requestId

Remarque : Remplacez ruleId par votre ID de règle.

Filtrer en fonction de requêtes avec un CAPTCHA non valide

Pour filtrer les 100 principales requêtes avec un CAPTCHA non valide, exécutez la requête suivante.

fields @timestamp, httpRequest.clientIp, httpRequest.requestId, captchaResponse.failureReason, @message| filter captchaResponse.failureReason ='TOKEN_MISSING'
| sort @timestamp desc
| limit 100

Remarque : Remplacez 100 dans la clause limite par le nombre de demandes pour lesquelles vous souhaitez filtrer.

Cette requête indique l'heure de la demande, l'adresse IP, l'ID de la demande, le code de réponse et l'intégralité du message.