WAF : protéger une ALB / CloudFront
À la fin de ce tutoriel, vous distinguerez AWS WAF, Security Groups, NACL et Shield, créerez une Web ACL WAFv2 (scope REGIONAL pour ALB ou CLOUDFRONT), attacherez des managed rule groups (CommonRuleSet, SQLi) et une rate-based rule, associerez la Web ACL à une ressource, configurerez un aperçu de logging, testerez un blocage prudent, puis nettoierez — profil
lab, région labca-central-1(API CloudFront =us-east-1).Niveau : Intermédiaire → Avancé · Temps estimé : 55–70 min · Versions testées : AWS WAF 2026, AWS CLI v2 (wafv2) · Dernière vérification : 2026-09-10 · Region lab :
ca-central-1(Web ACL CloudFront : API us-east-1, scope global)Slug :
aws-waf-alb-cloudfront· Série : AWS Solutions Architect · Mot-clé SEO : AWS WAF← Précédent : EKS + Ingress / load balancing · → Suivant : Quiz & FAQ Solutions Architect · Hub : Démarrer avec AWS
Prérequis
- Une ALB existante (équilibrage ALB ou Ingress EKS #30) ou une distribution CloudFront (#10)
- Profil AWS CLI
lab; AWS CLI v2 avec sous-commandewafv2 - Notions HTTP (méthodes, headers, paths) et SG vs NACL
- Aucun secret dans les commandes ; placeholders pour ARN ALB / Distribution ID
- Budget WAF (ordre de grandeur 2026, vérifier pricing AWS) :
- Web ACL : ~5 USD/mois
- Règles / rule groups : ~1 USD/mois par règle (managed groups facturés aussi)
- Requêtes analysées : ~0,60 USD / million
- Logging S3/CloudWatch : coûts stockage / ingestion en plus
- Lab court : créez, testez, disassociate + delete la Web ACL
export AWS_PROFILE=lab
export AWS_DEFAULT_REGION=ca-central-1
aws sts get-caller-identity
# ALB (région ca-central-1) — remplacez ou laissez placeholder
# ALB_ARN="arn:aws:elasticloadbalancing:ca-central-1:ACCOUNT:loadbalancer/app/lab-alb/xxxx"
# CloudFront (API WAF toujours us-east-1) :
# DIST_ID="E123EXAMPLE"
Ce que nous allons construire
Internet / curl (User-Agent ou path de test)
│
▼
┌─────────────────────────────────────┐
│ AWS WAF — Web ACL (WAFv2) │
│ • Managed: CommonRuleSet + SQLi │
│ • Rate-based (ex. 2000 req / 5 min)│
│ Scope REGIONAL (ALB) │
│ ou CLOUDFRONT (us-east-1 API) │
└──────────────┬──────────────────────┘
│ associate-web-acl
▼
┌─────────────────────────────────────┐
│ ALB (ca-central-1) OU CloudFront │
│ → targets / origin (S3, EC2…) │
└─────────────────────────────────────┘
│ (option)
▼
Logs → S3 ou CloudWatch Logs
(Schéma — alt : « AWS WAF Web ACL avec managed rules et rate-based devant ALB régionale ou CloudFront, logs vers S3/CloudWatch ».)
Étape 1 — WAF vs Security Groups / NACL / Shield (examen)
| Contrôle | Couche | Ce qu’il filtre | Stateful ? | Examen / prod |
|---|---|---|---|---|
| Security Group | L3/L4 (ENI) | IP, ports, protocoles | Oui | Première ligne VPC ; pas de SQLi/XSS |
| NACL | L3/L4 (subnet) | CIDR, ports ; allow et deny | Non | Filet subnet ; pas de contenu HTTP |
| AWS WAF | L7 (HTTP/S) | Headers, URI, body, géo, rate, OWASP | N/A (règles web) | OWASP, bots, rate limit applicatif |
| AWS Shield | DDoS (L3/L4 + edge) | Volumétrique / protocol ; Standard gratuit | N/A | Shield Standard inclus ; Advanced = SLA + WAF credits |
Piège certif : SG/NACL ne remplacent pas WAF. Shield Standard ≠ WAF. WAF s’attache à ALB, API Gateway, AppSync, Cognito (régional) ou CloudFront (global).
Étape 2 — Web ACL régionale vs CloudFront
| REGIONAL | CLOUDFRONT | |
|---|---|---|
| Scope CLI | --scope REGIONAL |
--scope CLOUDFRONT |
| Région API | Celle de la ressource (ca-central-1) |
Toujours us-east-1 pour wafv2 |
| Ressources | ALB, API Gateway stage, AppSync… | Distributions CloudFront |
| Nom | Unique par Region + compte | Unique globalement (scope CF) |
Pour CloudFront, même si votre distribution sert le Canada, les appels create-web-acl / associate-web-acl passent par --region us-east-1. Pour une ALB en ca-central-1, restez en ca-central-1.
Étape 3 — Managed rule groups + rate-based
AWS fournit des AWS Managed Rules à activer dans la Web ACL :
- AWSManagedRulesCommonRuleSet — protections OWASP courantes (XSS, mauvais User-Agent, etc.)
- AWSManagedRulesSQLiRuleSet — injections SQL typiques
- Autres (option) : KnownBadInputs, Linux/Unix, IP reputation…
Une rate-based rule compte les requêtes par IP (fenêtre ~5 min) et bloque au-delà du seuil (ex. 2000). Idéale contre brute-force / scraping agressif — à calibrer pour ne pas bloquer un NAT partagé légitime.
Priorité : plus le numéro est bas, plus la règle est évaluée tôt. Default action de la Web ACL : souvent Allow ; les règles bloquent explicitement.
Étape 4 — Lab minimal : create-web-acl (REGIONAL / ALB)
Adaptez le JSON ; pas de secrets. Placeholder ARN ALB.
export AWS_DEFAULT_REGION=ca-central-1
ALB_ARN="arn:aws:elasticloadbalancing:ca-central-1:ACCOUNT_ID:loadbalancer/app/lab-alb/PLACEHOLDER"
# Fichier règles (managed + rate-based)
cat > /tmp/waf-rules.json << 'EOF'
[
{
"Name": "AWS-AWSManagedRulesCommonRuleSet",
"Priority": 10,
"OverrideAction": { "None": {} },
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesCommonRuleSet"
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "CommonRuleSet"
}
},
{
"Name": "AWS-AWSManagedRulesSQLiRuleSet",
"Priority": 20,
"OverrideAction": { "None": {} },
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesSQLiRuleSet"
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "SQLiRuleSet"
}
},
{
"Name": "LabRateLimit",
"Priority": 30,
"Action": { "Block": {} },
"Statement": {
"RateBasedStatement": {
"Limit": 2000,
"AggregateKeyType": "IP"
}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "LabRateLimit"
}
}
]
EOF
aws wafv2 create-web-acl
--name lab-waf-alb
--scope REGIONAL
--default-action Allow={}
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=labWafAlb
--rules file:///tmp/waf-rules.json
--region ca-central-1
Récupérez l’ARN / Id / LockToken :
aws wafv2 list-web-acls --scope REGIONAL --region ca-central-1
--query "WebACLs[?Name=='lab-waf-alb']" --output table
WEB_ACL_ARN=$(aws wafv2 list-web-acls --scope REGIONAL --region ca-central-1
--query "WebACLs[?Name=='lab-waf-alb'].ARN" --output text)
Association à l’ALB :
aws wafv2 associate-web-acl
--web-acl-arn "$WEB_ACL_ARN"
--resource-arn "$ALB_ARN"
--region ca-central-1
Variante CloudFront (API us-east-1, scope CLOUDFRONT) :
# Même structure de rules ; changez --scope CLOUDFRONT et --region us-east-1
# aws wafv2 create-web-acl --name lab-waf-cf --scope CLOUDFRONT ... --region us-east-1
# aws wafv2 associate-web-acl --web-acl-arn "$WEB_ACL_ARN"
# --resource-arn "arn:aws:cloudfront::ACCOUNT:distribution/$DIST_ID" --region us-east-1
Étape 5 — Logging (aperçu S3 / CloudWatch)
Sans logs, le debug des faux positifs est aveugle. Aperçu :
- Créer une destination : bucket S3 (préfixe
aws-waf-logs-…obligatoire pour S3) ou log group CloudWatch. put-logging-configurationsur la Web ACL (ARN destination + champs redacted éventuels).- Coût : volume de logs + stockage. En lab, activez brièvement ou utilisez Sampled requests dans la console (gratuit, échantillon).
# Exemple conceptuel — adapter ARN log / policy bucket
# aws wafv2 put-logging-configuration --logging-configuration
# 'ResourceArn='"$WEB_ACL_ARN"',LogDestinationConfigs=["arn:aws:s3:::aws-waf-logs-lab-xxx"]'
Métriques CloudWatch : AllowedRequests, BlockedRequests par Web ACL / règle.
Étape 6 — Test prudent (User-Agent / path)
Prudence : ne testez que votre lab (ALB/CloudFront à vous). Pas de scan agressif, pas de payloads destructeurs hors lab isolé. Les managed rules bloquent souvent des User-Agents « mauvais » ou des patterns type SQLi dans la query string.
# Remplacez par le DNS de votre ALB ou domaine CloudFront
TARGET="http://lab-alb-xxxxx.ca-central-1.elb.amazonaws.com/"
# 1) Requête « normale » — doit passer (default Allow + pas de match)
curl -sI "$TARGET" | head -5
# 2) User-Agent souvent flaggé par CommonRuleSet (peut renvoyer 403)
curl -sI -A "Nikto" "$TARGET" | head -5
# 3) Path / query simulé « SQLi » (lab uniquement)
curl -sI "$TARGET?id=1'%20OR%20'1'='1" | head -5
Interprétez : 403 + métrique BlockedRequests = WAF actif. Si tout passe en 200, vérifiez l’association (list-resources-for-web-acl) et le délai de propagation (surtout CloudFront).
False positive fréquent : un User-Agent custom ou un body JSON légitime matché par CommonRuleSet → rule action override Count, ou exclusion de label (hors scope lab minimal).
Étape 7 — Vérification
| Check | Attendu |
|---|---|
list-web-acls |
lab-waf-alb visible (scope REGIONAL) |
list-resources-for-web-acl |
ARN ALB (ou distribution) listé |
curl normal |
200 (ou réponse app) |
curl -A Nikto / query SQLi |
souvent 403 |
| Métriques CW | BlockedRequests > 0 après tests |
| Coût | Web ACL + rules + requêtes — supprimer après lab |
aws wafv2 list-resources-for-web-acl
--web-acl-arn "$WEB_ACL_ARN"
--resource-type APPLICATION_LOAD_BALANCER
--region ca-central-1
Nettoyage
# 1) Dissocier
aws wafv2 disassociate-web-acl
--resource-arn "$ALB_ARN"
--region ca-central-1
# 2) LockToken puis delete Web ACL
TOKEN=$(aws wafv2 get-web-acl --name lab-waf-alb --scope REGIONAL
--id $(aws wafv2 list-web-acls --scope REGIONAL --region ca-central-1
--query "WebACLs[?Name=='lab-waf-alb'].Id" --output text)
--region ca-central-1 --query 'LockToken' --output text)
aws wafv2 delete-web-acl --name lab-waf-alb --scope REGIONAL
--id $(aws wafv2 list-web-acls --scope REGIONAL --region ca-central-1
--query "WebACLs[?Name=='lab-waf-alb'].Id" --output text)
--lock-token "$TOKEN" --region ca-central-1
Pour CloudFront : mêmes appels avec --scope CLOUDFRONT --region us-east-1. Supprimez aussi la config de logging et le bucket aws-waf-logs-* si créé. Une Web ACL oubliée = ~5 USD/mois + rules.
Erreurs fréquentes
| Symptôme | Cause | Correction |
|---|---|---|
WAFInvalidParameterException scope CF |
API hors us-east-1 |
--region us-east-1 + --scope CLOUDFRONT |
| Association refuse | Mauvais scope / ARN | REGIONAL↔ALB ; CLOUDFRONT↔distribution |
| Tout en 200 malgré rules | Pas associé / propagation | list-resources-for-web-acl ; attendre CF |
| 403 sur trafic légitime | CommonRuleSet trop strict | Override Count / exclusions ; logs |
delete-web-acl échoue |
Encore associé ou LockToken stale | Disassociate d’abord ; get-web-acl pour token |
| Facture surprise | Web ACL + managed rules idle | Nettoyage systématique après lab |
| Bucket logs rejeté | Nom sans préfixe aws-waf-logs- |
Renommer le bucket S3 |
Quiz (3 questions)
1. Pour protéger une ALB en ca-central-1, la Web ACL WAFv2 utilise :
– A. Scope CLOUDFRONT en us-east-1 uniquement
– B. Scope REGIONAL dans la Region de l’ALB
– C. Un Security Group L7
2. AWSManagedRulesCommonRuleSet et SQLiRuleSet sont :
– A. Des NACL numérotées
– B. Des AWS Managed Rule groups L7 (OWASP / SQLi)
– C. Des policies IAM
3. Avant de supprimer une Web ACL facturée, la première action est :
– A. Supprimer le VPC
– B. Disassociate la ressource (ALB/CloudFront), puis delete-web-acl
– C. Désactiver Shield Standard
Réponses : 1‑B · 2‑B · 3‑B
Pour aller plus loin
- AWS WAF Developer Guide
- AWS Managed Rules
- Logging Web ACL
- Shield vs WAF
- Suite : Quiz & FAQ Solutions Architect — pilier révision certif (#32)
Maillage série AWS (P1)
| ← Précédent | EKS + Ingress / load balancing |
| → Suivant | Quiz & FAQ Solutions Architect |
| Aussi | Démarrer avec AWS · ALB · CloudFront + S3 · SG vs NACL |
Retour parcours AWS — hub de la série et leçons sœurs.



