

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# AWS WAF Journaux de requêtes
<a name="waf-logs"></a>

AWS WAF est un pare-feu d'applications Web qui vous permet de surveiller et de contrôler les requêtes HTTP et HTTPS que vos applications Web protégées reçoivent de la part des clients. Vous définissez comment traiter les requêtes Web en configurant des règles dans une liste de contrôle d'accès AWS WAF Web (ACL). Vous protégez ensuite une application Web en lui associant une ACL Web. Parmi les ressources d'applications Web que vous pouvez protéger, AWS WAF citons les CloudFront distributions Amazon, Amazon API APIs Gateway REST et les équilibreurs de charge d'application. Pour plus d'informations AWS WAF, consultez [AWS WAF](https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html)le *guide du AWS WAF développeur*.

AWS WAF les journaux incluent des informations sur le trafic analysé par votre ACL Web, telles que l'heure à laquelle la demande AWS WAF a été reçue de votre AWS ressource, des informations détaillées sur la demande et l'action pour la règle à laquelle chaque demande correspond.

Vous pouvez configurer une ACL AWS WAF Web pour publier les journaux vers l'une des nombreuses destinations, où vous pouvez les interroger et les consulter. Pour plus d'informations sur la configuration de la journalisation des ACL Web et du contenu des AWS WAF journaux, consultez la section [Journalisation du trafic ACL AWS WAF Web](https://docs.aws.amazon.com/waf/latest/developerguide/logging.html) dans le *guide du AWS WAF développeur*.

Pour savoir comment utiliser Athena pour analyser les AWS WAF journaux afin d'obtenir des informations sur la détection des menaces et les attaques de sécurité potentielles, consultez le billet de blog consacré aux AWS réseaux et [à la diffusion de contenu Comment utiliser les requêtes Amazon Athena pour AWS WAF analyser les journaux et fournir la visibilité nécessaire à la](https://aws.amazon.com/blogs/networking-and-content-delivery/how-to-use-amazon-athena-queries-to-analyze-aws-waf-logs-and-provide-the-visibility-needed-for-threat-detection/) détection des menaces.

Pour savoir comment agréger les AWS WAF journaux dans un référentiel central de lacs de données et les interroger avec Athena, consultez le billet de blog sur le AWS Big Data [Analyzing AWS WAF logs with OpenSearch Service, Amazon Athena](https://aws.amazon.com/blogs/big-data/analyzing-aws-waf-logs-with-amazon-es-amazon-athena-and-amazon-quicksight/) et Quick.

Cette rubrique fournit des exemples d’instructions `CREATE TABLE` pour la projection de partition et le partitionnement manuel, ainsi qu’un exemple qui n’utilise pas le partitionnement.

**Note**  
Les instructions `CREATE TABLE` de cette rubrique peuvent être utilisées à la fois pour les journaux AWS WAF v1 et v2. Dans v1, le champ `webaclid` contient une ID. Dans v2, le champ `webaclid` contient un ARN complet. Les instructions `CREATE TABLE` ici traitent ce contenu de manière agnostique à l'aide du type de données `string`.

**Topics**
+ [Création d'une table pour les journaux AWS WAF S3 dans Athena à l'aide de la projection de partitions](create-waf-table-partition-projection.md)
+ [Créer une table pour les journaux AWS WAF S3 dans Athena à l'aide d'une partition manuelle](create-waf-table-manual-partition.md)
+ [Création d'une table pour les AWS WAF journaux sans partitionnement](create-waf-table.md)
+ [Exemples de requêtes pour les AWS WAF journaux](query-examples-waf-logs.md)

# Création d'une table pour les journaux AWS WAF S3 dans Athena à l'aide de la projection de partitions
<a name="create-waf-table-partition-projection"></a>

Comme AWS WAF les journaux ont une structure connue dont vous pouvez spécifier le schéma de partition à l'avance, vous pouvez réduire le temps d'exécution des requêtes et automatiser la gestion des partitions en utilisant la fonction de [projection de partition](partition-projection.md) Athena. La projection des partitions ajoute automatiquement de nouvelles partitions à mesure que de nouvelles données sont ajoutées. Vous n'avez donc plus besoin d'ajouter manuellement des partitions à l'aide de la commande `ALTER TABLE ADD PARTITION`. 

L'exemple d'`CREATE TABLE`instruction suivant utilise automatiquement la projection de partitions sur AWS WAF les journaux à partir d'une date spécifiée jusqu'à aujourd'hui pour quatre AWS régions différentes. La clause `PARTITION BY` dans cet exemple, partitionne par région et par date, mais vous pouvez modifier les partitions en fonction de vos besoins. Modifiez les champs si nécessaire pour qu'ils correspondent à la sortie de votre journal. Dans les `storage.location.template` clauses `LOCATION` et, remplacez les *AWS\$1ACCOUNT\$1NUMBER* espaces réservés *amzn-s3-demo-bucket* et par des valeurs identifiant l'emplacement du compartiment Amazon S3 dans lequel se trouvent vos AWS WAF journaux. Pour`projection.day.range`, remplacez*2021*/*01*/*01*par la date de début que vous souhaitez utiliser. Après avoir exécuté la requête avec succès, vous pouvez interroger la table. Vous n'avez pas besoin d'exécuter `ALTER TABLE ADD PARTITION` pour charger les partitions. 

```
CREATE EXTERNAL TABLE `waf_logs_partition_projection`(
  `timestamp` bigint, 
  `formatversion` int, 
  `webaclid` string, 
  `terminatingruleid` string, 
  `terminatingruletype` string, 
  `action` string, 
  `terminatingrulematchdetails` array<struct<conditiontype:string,sensitivitylevel:string,location:string,matcheddata:array<string>>>, 
  `httpsourcename` string, 
  `httpsourceid` string, 
  `rulegrouplist` array<struct<rulegroupid:string,terminatingrule:struct<ruleid:string,action:string,rulematchdetails:array<struct<conditiontype:string,sensitivitylevel:string,location:string,matcheddata:array<string>>>>,nonterminatingmatchingrules:array<struct<ruleid:string,action:string,overriddenaction:string,rulematchdetails:array<struct<conditiontype:string,sensitivitylevel:string,location:string,matcheddata:array<string>>>,challengeresponse:struct<responsecode:string,solvetimestamp:string>,captcharesponse:struct<responsecode:string,solvetimestamp:string>>>,excludedrules:string>>, 
  `ratebasedrulelist` array<struct<ratebasedruleid:string,limitkey:string,maxrateallowed:int>>, 
  `nonterminatingmatchingrules` array<struct<ruleid:string,action:string,rulematchdetails:array<struct<conditiontype:string,sensitivitylevel:string,location:string,matcheddata:array<string>>>,challengeresponse:struct<responsecode:string,solvetimestamp:string>,captcharesponse:struct<responsecode:string,solvetimestamp:string>>>, 
  `requestheadersinserted` array<struct<name:string,value:string>>, 
  `responsecodesent` string, 
  `httprequest` struct<clientip:string,country:string,headers:array<struct<name:string,value:string>>,uri:string,args:string,httpversion:string,httpmethod:string,requestid:string,fragment:string,scheme:string,host:string>,
  `labels` array<struct<name:string>>, 
  `captcharesponse` struct<responsecode:string,solvetimestamp:string,failurereason:string>, 
  `challengeresponse` struct<responsecode:string,solvetimestamp:string,failurereason:string>, 
  `ja3fingerprint` string, 
  `ja4fingerprint` string, 
  `oversizefields` string, 
  `requestbodysize` int, 
  `requestbodysizeinspectedbywaf` int)
  PARTITIONED BY ( 
   `log_time` string)
ROW FORMAT SERDE 
  'org.openx.data.jsonserde.JsonSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  's3://amzn-s3-demo-bucket/AWSLogs/AWS_ACCOUNT_NUMBER/WAFLogs/cloudfront/testui/'
TBLPROPERTIES (
 'projection.enabled'='true',
  'projection.log_time.format'='yyyy/MM/dd/HH/mm',
  'projection.log_time.interval'='1',
  'projection.log_time.interval.unit'='minutes',
  'projection.log_time.range'='2025/01/01/00/00,NOW',
  'projection.log_time.type'='date',
  'storage.location.template'='s3://amzn-s3-demo-bucket/AWSLogs/AWS_ACCOUNT_NUMBER/WAFLogs/cloudfront/testui/${log_time}')
```

**Note**  
Le format du chemin indiqué dans la `LOCATION` clause de l'exemple est standard mais peut varier en fonction de la AWS WAF configuration que vous avez implémentée. Par exemple, l'exemple de chemin de AWS WAF journal suivant concerne une CloudFront distribution :   

```
s3://amzn-s3-demo-bucket/AWSLogs/AWS_ACCOUNT_NUMBER/WAFLogs/cloudfront/cloudfronyt/2025/01/01/00/00/
```
Si vous rencontrez des problèmes lors de la création ou de l'interrogation de votre table de AWS WAF journaux, confirmez l'emplacement de vos données de journal ou de votre [contact Support](https://console.aws.amazon.com/support/home/).

Pour plus d'informations sur la projection de partition, voir [Utilisation de la projection de partition avec Amazon Athena](partition-projection.md).

# Créer une table pour les journaux AWS WAF S3 dans Athena à l'aide d'une partition manuelle
<a name="create-waf-table-manual-partition"></a>

Cette section décrit comment créer une table pour les AWS WAF journaux à l'aide d'une partition manuelle.

Dans les `storage.location.template` clauses `LOCATION` et, remplacez les *AWS\$1ACCOUNT\$1NUMBER* espaces réservés *amzn-s3-demo-bucket* et par des valeurs identifiant l'emplacement du compartiment Amazon S3 dans lequel se trouvent vos AWS WAF journaux.

```
CREATE EXTERNAL TABLE `waf_logs_manual_partition`(
  `timestamp` bigint, 
  `formatversion` int, 
  `webaclid` string, 
  `terminatingruleid` string, 
  `terminatingruletype` string, 
  `action` string, 
  `terminatingrulematchdetails` array<struct<conditiontype:string,sensitivitylevel:string,location:string,matcheddata:array<string>>>, 
  `httpsourcename` string, 
  `httpsourceid` string, 
  `rulegrouplist` array<struct<rulegroupid:string,terminatingrule:struct<ruleid:string,action:string,rulematchdetails:array<struct<conditiontype:string,sensitivitylevel:string,location:string,matcheddata:array<string>>>>,nonterminatingmatchingrules:array<struct<ruleid:string,action:string,overriddenaction:string,rulematchdetails:array<struct<conditiontype:string,sensitivitylevel:string,location:string,matcheddata:array<string>>>,challengeresponse:struct<responsecode:string,solvetimestamp:string>,captcharesponse:struct<responsecode:string,solvetimestamp:string>>>,excludedrules:string>>, 
  `ratebasedrulelist` array<struct<ratebasedruleid:string,limitkey:string,maxrateallowed:int>>, 
  `nonterminatingmatchingrules` array<struct<ruleid:string,action:string,rulematchdetails:array<struct<conditiontype:string,sensitivitylevel:string,location:string,matcheddata:array<string>>>,challengeresponse:struct<responsecode:string,solvetimestamp:string>,captcharesponse:struct<responsecode:string,solvetimestamp:string>>>, 
  `requestheadersinserted` array<struct<name:string,value:string>>, 
  `responsecodesent` string, 
  `httprequest` struct<clientip:string,country:string,headers:array<struct<name:string,value:string>>,uri:string,args:string,httpversion:string,httpmethod:string,requestid:string,fragment:string,scheme:string,host:string>, 
  `labels` array<struct<name:string>>, 
  `captcharesponse` struct<responsecode:string,solvetimestamp:string,failurereason:string>, 
  `challengeresponse` struct<responsecode:string,solvetimestamp:string,failurereason:string>, 
  `ja3fingerprint` string, 
  `ja4fingerprint` string, 
  `oversizefields` string, 
  `requestbodysize` int, 
  `requestbodysizeinspectedbywaf` int)
  PARTITIONED BY ( `year` string, `month` string, `day` string, `hour` string, `min` string)
ROW FORMAT SERDE 
  'org.openx.data.jsonserde.JsonSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  's3://amzn-s3-demo-bucket/AWSLogs/AWS_ACCOUNT_NUMBER/WAFLogs/cloudfront/webacl/'
```

# Création d'une table pour les AWS WAF journaux sans partitionnement
<a name="create-waf-table"></a>

Cette section explique comment créer une table pour les AWS WAF journaux sans partitionnement ni projection de partition.

**Note**  
Pour des raisons de performance et de coût, l’utilisation d’un schéma non partitionné pour les requêtes est déconseillée. Pour plus d'informations, consultez les [10 meilleurs conseils d'optimisation des performances pour Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/) sur le blog AWS Big Data.

**Pour créer le AWS WAF tableau**

1. Copiez et collez l'instruction DDL suivante dans la console Athena. Modifiez les champs si nécessaire pour qu'ils correspondent à la sortie de votre journal. Modifiez l'emplacement `LOCATION` pour le compartiment Amazon S3 correspondant à celui qui stocke vos journaux.

   Cette requête utilise le [OpenX JSON SerDe](openx-json-serde.md).
**Note**  
Il SerDe s'attend à ce que chaque document JSON se trouve sur une seule ligne de texte sans aucun caractère de fin de ligne séparant les champs de l'enregistrement. Si le texte JSON est dans un joli format d'impression, vous pouvez recevoir un message d'erreur tel que HIVE\$1CURSOR\$1ERROR : Row is not a valid JSON Object ou HIVE\$1CURSOR\$1ERROR : : Unexpected JsonParseException end-of-input : expected close marker for OBJECT lorsque vous essayez d'interroger la table après l'avoir créée. Pour plus d'informations, consultez la section [Fichiers de données JSON](https://github.com/rcongiu/Hive-JSON-Serde#json-data-files) dans la SerDe documentation OpenX sur. GitHub 

   ```
   CREATE EXTERNAL TABLE `waf_logs`(
     `timestamp` bigint,
     `formatversion` int,
     `webaclid` string,
     `terminatingruleid` string,
     `terminatingruletype` string,
     `action` string,
     `terminatingrulematchdetails` array <
                                       struct <
                                           conditiontype: string,
                                           sensitivitylevel: string,
                                           location: string,
                                           matcheddata: array < string >
                                             >
                                        >,
     `httpsourcename` string,
     `httpsourceid` string,
     `rulegrouplist` array <
                         struct <
                             rulegroupid: string,
                             terminatingrule: struct <
                                                 ruleid: string,
                                                 action: string,
                                                 rulematchdetails: array <
                                                                      struct <
                                                                          conditiontype: string,
                                                                          sensitivitylevel: string,
                                                                          location: string,
                                                                          matcheddata: array < string >
                                                                             >
                                                                       >
                                                   >,
                             nonterminatingmatchingrules: array <
                                                                 struct <
                                                                     ruleid: string,
                                                                     action: string,
                                                                     overriddenaction: string,
                                                                     rulematchdetails: array <
                                                                                          struct <
                                                                                              conditiontype: string,
                                                                                              sensitivitylevel: string,
                                                                                              location: string,
                                                                                              matcheddata: array < string >
                                                                                                 >
                                                                      >,
                                                                     challengeresponse: struct <
                                                                               responsecode: string,
                                                                               solvetimestamp: string
                                                                                 >,
                                                                     captcharesponse: struct <
                                                                               responsecode: string,
                                                                               solvetimestamp: string
                                                                                 >
                                                                       >
                                                                >,
                             excludedrules: string
                               >
                          >,
   `ratebasedrulelist` array <
                            struct <
                                ratebasedruleid: string,
                                limitkey: string,
                                maxrateallowed: int
                                  >
                             >,
     `nonterminatingmatchingrules` array <
                                       struct <
                                           ruleid: string,
                                           action: string,
                                           rulematchdetails: array <
                                                                struct <
                                                                    conditiontype: string,
                                                                    sensitivitylevel: string,
                                                                    location: string,
                                                                    matcheddata: array < string >
                                                                       >
                                                                >,
                                           challengeresponse: struct <
                                                               responsecode: string,
                                                               solvetimestamp: string
                                                                >,
                                           captcharesponse: struct <
                                                               responsecode: string,
                                                               solvetimestamp: string
                                                                >
                                             >
                                        >,
     `requestheadersinserted` array <
                                   struct <
                                       name: string,
                                       value: string
                                         >
                                    >,
     `responsecodesent` string,
     `httprequest` struct <
                       clientip: string,
                       country: string,
                       headers: array <
                                   struct <
                                       name: string,
                                       value: string
                                         >
                                    >,
                       uri: string,
                       args: string,
                       httpversion: string,
                       httpmethod: string,
                       requestid: string
                         >,
     `labels` array <
                  struct <
                      name: string
                        >
                   >,
     `captcharesponse` struct <
                           responsecode: string,
                           solvetimestamp: string,
                           failureReason: string
                             >,
     `challengeresponse` struct <
                           responsecode: string,
                           solvetimestamp: string,
                           failureReason: string
                           >,
     `ja3Fingerprint` string,
     `oversizefields` string,
     `requestbodysize` int,
     `requestbodysizeinspectedbywaf` int
   )
   ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
   STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
   OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
   LOCATION 's3://amzn-s3-demo-bucket/prefix/'
   ```

1. Exécutez l'instruction `CREATE EXTERNAL TABLE` dans l'éditeur de requête de la console Athena. Cette opération permet d'enregistrer la table `waf_logs` et de mettre les données qu'elle contient à la disposition des requêtes d'Athena.

# Exemples de requêtes pour les AWS WAF journaux
<a name="query-examples-waf-logs"></a>

Une grande partie des exemples de requêtes utilise la table de projection de partition créée précédemment. Dans les exemples de requêtes suivants, modifiez le nom de la table, les valeurs des colonnes et les autres variables en fonction de vos besoins. Pour augmenter les performances de vos requêtes et réduire les coûts, ajoutez la colonne de partition dans la condition de filtre.

**Topics**
+ [Comptabilisation des référents, des adresses IP ou des règles correspondantes](query-examples-waf-logs-count.md)
+ [Requête utilisant la date et l’heure](query-examples-waf-logs-date-time.md)
+ [Requête portant sur des demandes ou des adresses bloquées](query-examples-waf-logs-blocked-requests.md)

# Comptabilisation des référents, des adresses IP ou des règles correspondantes
<a name="query-examples-waf-logs-count"></a>

Les exemples de cette section soumettent des requêtes de comptabilisation d’éléments d’intérêt des journaux.
+ [Count the number of referrers that contain a specified term](#waf-example-count-referrers-with-specified-term)
+ [Count all matched IP addresses in the last 10 days that have matched excluded rules](#waf-example-count-matched-ip-addresses)
+ [Group all counted managed rules by the number of times matched](#waf-example-group-managed-rules-by-times-matched)
+ [Group all counted custom rules by number of times matched](#waf-example-group-custom-rules-by-times-matched)

**Example – Comptage du nombre de référents qui contiennent un terme spécifié**  
La requête suivante compte le nombre de référents qui contiennent le terme « amazon » pour la plage de dates spécifiée.  

```
WITH test_dataset AS 
  (SELECT header FROM waf_logs
    CROSS JOIN UNNEST(httprequest.headers) AS t(header) WHERE "date" >= '2021/03/01'
    AND "date" < '2021/03/31')
SELECT COUNT(*) referer_count 
FROM test_dataset 
WHERE LOWER(header.name)='referer' AND header.value LIKE '%amazon%'
```

**Example – Comptage de toutes les adresses IP correspondant à des règles d'exclusion au cours des 10 derniers jours**  
La requête suivante compte le nombre de fois, au cours des 10 derniers jours, où l'adresse IP correspond à la règle d'exclusion dans le groupe de règles.   

```
WITH test_dataset AS 
  (SELECT * FROM waf_logs 
    CROSS JOIN UNNEST(rulegrouplist) AS t(allrulegroups))
SELECT 
  COUNT(*) AS count, 
  "httprequest"."clientip", 
  "allrulegroups"."excludedrules",
  "allrulegroups"."ruleGroupId"
FROM test_dataset 
WHERE allrulegroups.excludedrules IS NOT NULL AND from_unixtime(timestamp/1000) > now() - interval '10' day
GROUP BY "httprequest"."clientip", "allrulegroups"."ruleGroupId", "allrulegroups"."excludedrules"
ORDER BY count DESC
```

**Example – Regroupement de toutes les règles gérées comptées en fonction du nombre de fois qu'elles ont été mises en correspondance**  
Si vous avez défini les actions de règles du groupe de règles sur Count dans votre configuration ACL Web avant le 27 octobre 2022, vous AWS WAF avez enregistré vos remplacements dans le fichier JSON de l'ACL Web sous `excludedRules` le nom de. Désormais, le paramètre JSON permettant de remplacer une règle par Comptage se trouve dans les paramètres `ruleActionOverrides`. Pour plus d'informations, consultez [Remplacements d'action dans les groupes de règles](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-rule-group-override-options.html) du *Guide du développeur AWS WAF *. Pour extraire les règles gérées en mode Comptage à partir de la nouvelle structure du journal, interrogez les `nonTerminatingMatchingRules` dans la section `ruleGroupList` plutôt que le champ `excludedRules`, comme dans l'exemple suivant.  

```
SELECT
 count(*) AS count,
 httpsourceid,
 httprequest.clientip,
 t.rulegroupid, 
 t.nonTerminatingMatchingRules
FROM "waf_logs" 
CROSS JOIN UNNEST(rulegrouplist) AS t(t) 
WHERE action <> 'BLOCK' AND cardinality(t.nonTerminatingMatchingRules) > 0 
GROUP BY t.nonTerminatingMatchingRules, action, httpsourceid, httprequest.clientip, t.rulegroupid 
ORDER BY "count" DESC 
Limit 50
```

**Example – Regroupement de toutes les règles personnalisées comptées en fonction du nombre de fois qu'elles ont été mises en correspondance**  
La requête suivante regroupe toutes les règles personnalisées comptées en fonction du nombre de fois qu'elles ont été mises en correspondance.  

```
SELECT
  count(*) AS count,
         httpsourceid,
         httprequest.clientip,
         t.ruleid,
         t.action
FROM "waf_logs" 
CROSS JOIN UNNEST(nonterminatingmatchingrules) AS t(t) 
WHERE action <> 'BLOCK' AND cardinality(nonTerminatingMatchingRules) > 0 
GROUP BY t.ruleid, t.action, httpsourceid, httprequest.clientip 
ORDER BY "count" DESC
Limit 50
```

Pour plus d'informations sur l'emplacement des journaux pour les règles personnalisées et les groupes de règles gérés, consultez [Surveillance et réglage](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-testing-activities.html) du *Guide du développeur AWS WAF *.

# Requête utilisant la date et l’heure
<a name="query-examples-waf-logs-date-time"></a>

Les exemples fournis dans cette section présentent des requêtes qui utilisent des valeurs de date et d’heure.
+ [Return the timestamp field in human-readable ISO 8601 format](#waf-example-return-human-readable-timestamp)
+ [Return records from the last 24 hours](#waf-example-return-records-last-24-hours)
+ [Return records for a specified date range and IP address](#waf-example-return-records-date-range-and-ip)
+ [For a specified date range, count the number of IP addresses in five minute intervals](#waf-example-count-ip-addresses-in-date-range)
+ [Count the number of X-Forwarded-For IP in the last 10 days](#waf-example-count-x-forwarded-for-ip)

**Example – Renvoi du champ d'horodatage au format ISO 8601 lisible par l'homme**  
La requête suivante utilise les fonctions `from_unixtime` et `to_iso8601` pour renvoyer le champ `timestamp` dans un format ISO 8601 lisible par l'homme (par exemple, `2019-12-13T23:40:12.000Z` au lieu de `1576280412771`). La requête renvoie également le nom de la source HTTP, l'ID de la source et la requête.   

```
SELECT to_iso8601(from_unixtime(timestamp / 1000)) as time_ISO_8601,
       httpsourcename,
       httpsourceid,
       httprequest
FROM waf_logs
LIMIT 10;
```

**Example – Renvoi des enregistrements des dernières 24 heures**  
La requête suivante utilise un filtre dans la clause `WHERE` pour renvoyer les champs Nom de la source HTTP, ID de la source HTTP et Requête HTTP pour les registres des dernières 24 heures.  

```
SELECT to_iso8601(from_unixtime(timestamp/1000)) AS time_ISO_8601, 
       httpsourcename, 
       httpsourceid, 
       httprequest 
FROM waf_logs
WHERE from_unixtime(timestamp/1000) > now() - interval '1' day
LIMIT 10;
```

**Example – Renvoi des enregistrements pour une plage de dates et une adresse IP spécifiées**  
La requête suivante répertorie les registres dans une plage de dates spécifiée pour une adresse IP client spécifiée.  

```
SELECT * 
FROM waf_logs 
WHERE httprequest.clientip='53.21.198.66' AND "date" >= '2021/03/01' AND "date" < '2021/03/31'
```

**Example – Comptage du nombre d'adresses IP par intervalles de cinq minutes pour une plage de dates spécifiée**  
La requête suivante compte, pour une plage de dates particulière, le nombre d'adresses IP à intervalles de cinq minutes.  

```
WITH test_dataset AS 
  (SELECT 
     format_datetime(from_unixtime((timestamp/1000) - ((minute(from_unixtime(timestamp / 1000))%5) * 60)),'yyyy-MM-dd HH:mm') AS five_minutes_ts,
     "httprequest"."clientip" 
     FROM waf_logs 
     WHERE "date" >= '2021/03/01' AND "date" < '2021/03/31')
SELECT five_minutes_ts,"clientip",count(*) ip_count 
FROM test_dataset 
GROUP BY five_minutes_ts,"clientip"
```

**Example — Comptez le nombre d' X-Forwarded-Foradresses IP au cours des 10 derniers jours**  
La requête suivante filtre les en-têtes des demandes et compte le nombre d' X-Forwarded-Foradresses IP au cours des 10 derniers jours.  

```
WITH test_dataset AS
  (SELECT header
   FROM waf_logs
   CROSS JOIN UNNEST (httprequest.headers) AS t(header)
   WHERE from_unixtime("timestamp"/1000) > now() - interval '10' DAY) 
SELECT header.value AS ip,
       count(*) AS COUNT 
FROM test_dataset 
WHERE header.name='X-Forwarded-For' 
GROUP BY header.value 
ORDER BY COUNT DESC
```

Pour plus d'informations sur les fonctions de date et d'heure, veuillez consulter la rubrique [Date and time functions and operators](https://trino.io/docs/current/functions/datetime.html) dans la documentation Trino.

# Requête portant sur des demandes ou des adresses bloquées
<a name="query-examples-waf-logs-blocked-requests"></a>

Les exemples fournis dans cette section présentent des requêtes portant sur des demandes ou des adresses bloquées.
+ [Extract the top 100 IP addresses blocked by a specified rule type](#waf-example-extract-top-100-blocked-ip-by-rule)
+ [Count the number of times a request from a specified country has been blocked](#waf-example-count-request-blocks-from-country)
+ [Count the number of times a request has been blocked, grouping by specific attributes](#waf-example-count-request-blocks-by-attribute)
+ [Count the number of times a specific terminating rule ID has been matched](#waf-example-count-terminating-rule-id-matches)
+ [Retrieve the top 100 IP addresses blocked during a specified date range](#waf-example-top-100-ip-addresses-blocked-for-date-range)

**Example – Extraction des 100 premières adresses IP bloquées par un type de règle spécifié**  
La requête suivante extrait et compte les 100 premières adresses IP qui ont été bloquées par la règle de terminaison `RATE_BASED` pendant la période spécifiée.  

```
SELECT COUNT(httpRequest.clientIp) as count,
httpRequest.clientIp
FROM waf_logs
WHERE terminatingruletype='RATE_BASED' AND action='BLOCK' and "date" >= '2021/03/01'
AND "date" < '2021/03/31'
GROUP BY httpRequest.clientIp
ORDER BY count DESC
LIMIT 100
```

**Example – Comptage du nombre de fois où une demande provenant d'un pays donné a été bloquée**  
La requête suivante comptabilise le nombre de fois où la demande est arrivée à partir d'une adresse IP irlandaise (IE) et a été bloquée par la règle de résiliation `RATE_BASED`.  

```
SELECT 
  COUNT(httpRequest.country) as count, 
  httpRequest.country 
FROM waf_logs
WHERE 
  terminatingruletype='RATE_BASED' AND 
  httpRequest.country='IE'
GROUP BY httpRequest.country
ORDER BY count
LIMIT 100;
```

**Example – Comptage du nombre de fois où une demande a été bloquée, en regroupant par attributs spécifiques**  
La requête suivante compte le nombre de fois où la demande a été bloquée, les résultats étant regroupés par WebACL, RuleId ClientIP et URI de requête HTTP.  

```
SELECT 
  COUNT(*) AS count,
  webaclid,
  terminatingruleid,
  httprequest.clientip,
  httprequest.uri
FROM waf_logs
WHERE action='BLOCK'
GROUP BY webaclid, terminatingruleid, httprequest.clientip, httprequest.uri
ORDER BY count DESC
LIMIT 100;
```

**Example – Comptage du nombre de fois qu'un ID de règle de terminaison spécifique a été trouvé**  
La requête suivante comptabilise le nombre de fois où un ID de règle de résiliation spécifique a été mis en correspondance (`WHERE terminatingruleid='e9dd190d-7a43-4c06-bcea-409613d9506e'`). La requête regroupe ensuite les résultats par WebACL, Action, ClientIP et URI de requête HTTP.  

```
SELECT 
  COUNT(*) AS count,
  webaclid,
  action,
  httprequest.clientip,
  httprequest.uri
FROM waf_logs
WHERE terminatingruleid='e9dd190d-7a43-4c06-bcea-409613d9506e'
GROUP BY webaclid, action, httprequest.clientip, httprequest.uri
ORDER BY count DESC
LIMIT 100;
```

**Example – Récupération des 100 premières adresses IP bloquées pendant une plage de dates spécifiée**  
La requête suivante extrait les 100 premières adresses IP qui ont été bloquées pour une plage de dates spécifiée. La requête répertorie également le nombre de fois où les adresses IP ont été bloquées.  

```
SELECT "httprequest"."clientip", "count"(*) "ipcount", "httprequest"."country"
FROM waf_logs
WHERE "action" = 'BLOCK' and "date" >= '2021/03/01'
AND "date" < '2021/03/31'
GROUP BY "httprequest"."clientip", "httprequest"."country"
ORDER BY "ipcount" DESC limit 100
```