| name | waf |
| description | Manage AWS WAF web ACLs, rules, IP sets, and logging for CloudFront, ALB, and API Gateway via AWS CLI. |
| metadata | {"openclaw":{"emoji":"🛡️","requires":{"bins":["aws"]}}} |
AWS WAF
Use this skill for web application firewall operations: creating and managing web ACLs, configuring rules and rule groups, managing IP sets and regex pattern sets, associating WAF with resources, and analyzing WAF logs.
Prerequisites
- AWS CLI v2 configured with valid credentials
- IAM permissions:
wafv2:* for full access, or scoped policies
- For CloudFront: use
--scope CLOUDFRONT --region us-east-1
- For ALB/API Gateway/AppSync: use
--scope REGIONAL --region <region>
Common Operations
List and Inspect (Read-Only)
aws wafv2 list-web-acls --scope REGIONAL --region <region> --output table
aws wafv2 list-web-acls --scope CLOUDFRONT --region us-east-1 --output table
aws wafv2 get-web-acl \
--name <web-acl-name> \
--scope REGIONAL \
--id <web-acl-id> \
--region <region>
aws wafv2 get-web-acl \
--name <web-acl-name> --scope REGIONAL --id <web-acl-id> --region <region> \
--query 'WebACL.Rules[*].[Name,Priority,Action]' --output table
aws wafv2 list-available-managed-rule-groups --scope REGIONAL --region <region> --output table
aws wafv2 describe-managed-rule-group \
--vendor-name AWS \
--name AWSManagedRulesCommonRuleSet \
--scope REGIONAL --region <region>
aws wafv2 list-ip-sets --scope REGIONAL --region <region> --output table
aws wafv2 get-ip-set \
--name <ip-set-name> --scope REGIONAL --id <ip-set-id> --region <region>
aws wafv2 list-regex-pattern-sets --scope REGIONAL --region <region> --output table
aws wafv2 list-resources-for-web-acl \
--web-acl-arn <web-acl-arn> \
--resource-type APPLICATION_LOAD_BALANCER
aws wafv2 get-sampled-requests \
--web-acl-arn <web-acl-arn> \
--rule-metric-name <metric-name> \
--scope REGIONAL \
--time-window StartTime=$(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ),EndTime=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
--max-items 50 --region <region>
Create and Configure
⚠️ Cost note: WAF charges: $5/month per web ACL, $1/month per rule, $0.60 per million requests inspected. Managed rule groups may have additional subscription costs.
aws wafv2 create-ip-set \
--name <ip-set-name> \
--scope REGIONAL \
--ip-address-version IPV4 \
--addresses "192.0.2.0/24" "198.51.100.0/24" \
--region <region>
aws wafv2 create-web-acl \
--name <web-acl-name> \
--scope REGIONAL \
--default-action '{"Allow": {}}' \
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=<metric-name> \
--rules '[
{
"Name": "AWSCommonRules",
"Priority": 1,
"Statement": {
"ManagedRuleGroupStatement": {
"VendorName": "AWS",
"Name": "AWSManagedRulesCommonRuleSet"
}
},
"OverrideAction": {"None": {}},
"VisibilityConfig": {"SampledRequestsEnabled": true, "CloudWatchMetricsEnabled": true, "MetricName": "AWSCommonRules"}
}
]' \
--region <region>
aws wafv2 associate-web-acl \
--web-acl-arn <web-acl-arn> \
--resource-arn <alb-arn>
LOCK=$(aws wafv2 get-ip-set --name <ip-set-name> --scope REGIONAL --id <ip-set-id> --region <region> \
--query 'LockToken' --output text)
aws wafv2 update-ip-set \
--name <ip-set-name> --scope REGIONAL --id <ip-set-id> \
--addresses "192.0.2.0/24" "198.51.100.0/24" "203.0.113.0/24" \
--lock-token "$LOCK" --region <region>
aws wafv2 put-logging-configuration \
--logging-configuration '{
"ResourceArn": "<web-acl-arn>",
"LogDestinationConfigs": ["<firehose-delivery-stream-arn>"]
}'
Rate Limiting
Delete / Destructive
🛑 DESTRUCTIVE — Always confirm with the user before executing any of these commands.
aws wafv2 disassociate-web-acl --resource-arn <alb-arn>
LOCK=$(aws wafv2 get-web-acl --name <name> --scope REGIONAL --id <id> --region <region> \
--query 'LockToken' --output text)
aws wafv2 delete-web-acl --name <name> --scope REGIONAL --id <id> --lock-token "$LOCK" --region <region>
LOCK=$(aws wafv2 get-ip-set --name <name> --scope REGIONAL --id <id> --region <region> \
--query 'LockToken' --output text)
aws wafv2 delete-ip-set --name <name> --scope REGIONAL --id <id> --lock-token "$LOCK" --region <region>
Safety Rules
- NEVER delete or modify web ACLs without explicit user confirmation — may expose applications.
- NEVER expose or log AWS credentials.
- ALWAYS use Count mode first to test rules before switching to Block.
- ALWAYS confirm scope (REGIONAL vs CLOUDFRONT) before operations.
- WARN that removing a web ACL from a resource leaves it unprotected.
- WARN about managed rule group costs and WCU (Web ACL Capacity Unit) limits.
Best Practices
- Start with AWS Managed Rules (CommonRuleSet, SQLiRuleSet, KnownBadInputsRuleSet).
- Test new rules in Count mode before switching to Block.
- Enable sampled request logging to understand traffic patterns.
- Use rate-based rules to protect against DDoS and brute force.
- Monitor
BlockedRequests and AllowedRequests CloudWatch metrics.
Common Patterns
Pattern: Block Bad IPs
IP_SET=$(aws wafv2 create-ip-set \
--name blocked-ips \
--scope REGIONAL \
--ip-address-version IPV4 \
--addresses "1.2.3.4/32" "5.6.7.0/24" \
--region <region> \
--query 'Summary.Id' --output text)
Pattern: Production Web ACL with Common Protections
aws wafv2 create-web-acl \
--name production-waf \
--scope REGIONAL \
--default-action '{"Allow": {}}' \
--visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=production-waf \
--rules '[
{"Name":"CommonRules","Priority":1,"Statement":{"ManagedRuleGroupStatement":{"VendorName":"AWS","Name":"AWSManagedRulesCommonRuleSet"}},"OverrideAction":{"None":{}},"VisibilityConfig":{"SampledRequestsEnabled":true,"CloudWatchMetricsEnabled":true,"MetricName":"CommonRules"}},
{"Name":"SQLiRules","Priority":2,"Statement":{"ManagedRuleGroupStatement":{"VendorName":"AWS","Name":"AWSManagedRulesSQLiRuleSet"}},"OverrideAction":{"None":{}},"VisibilityConfig":{"SampledRequestsEnabled":true,"CloudWatchMetricsEnabled":true,"MetricName":"SQLiRules"}},
{"Name":"BadInputs","Priority":3,"Statement":{"ManagedRuleGroupStatement":{"VendorName":"AWS","Name":"AWSManagedRulesKnownBadInputsRuleSet"}},"OverrideAction":{"None":{}},"VisibilityConfig":{"SampledRequestsEnabled":true,"CloudWatchMetricsEnabled":true,"MetricName":"BadInputs"}}
]' \
--region <region>
Troubleshooting
| Error | Cause | Fix |
|---|
WAFNonexistentItemException | Resource not found | Verify name, id, and scope |
WAFOptimisticLockException | Stale lock token | Re-fetch the resource to get current lock token |
WAFLimitsExceededException | Exceeded WCU limit (1500 default) | Reduce rule complexity or request limit increase |
| Legitimate traffic blocked | Managed rule false positive | Use rule exclusions or switch specific rule to Count |
WAFInvalidParameterException on CloudFront | Wrong scope or region | Use --scope CLOUDFRONT --region us-east-1 |
| Logs not appearing | Logging not configured | Enable logging with put-logging-configuration |