Cloud Armor: Advanced WAF and DDoS Protection for GCP Workloads
Cloud Armor is GCP's global WAF and DDoS protection service. This guide configures production-grade security policies: OWASP ModSecurity Core Rule Set, rate limiting, geo-blocking, adaptive protection for DDoS mitigation, and threat intelligence-based rules.
Every public-facing application on the internet gets hit with automated attacks — SQL injection probes, cross-site scripting attempts, credential stuffing bots, and periodic volumetric DDoS attacks. Without application-layer protection, your backend services see all of this traffic and either spend compute processing it or get overwhelmed by it.
Cloud Armor is GCP's globally distributed WAF and DDoS mitigation service. It runs at Google's network edge — traffic is inspected and filtered before it reaches your load balancer, so malicious requests never consume backend resources. For DDoS specifically, Cloud Armor can absorb attacks at Google scale (multi-terabit capacity) without affecting your backend.
This guide implements a production Cloud Armor configuration: OWASP Core Rule Set for common web attack protection, rate limiting for bot and credential stuffing defense, geo-restrictions for compliance requirements, and Adaptive Protection for automated DDoS detection and response.
Cloud Armor Architecture
Cloud Armor security policies attach to backend services behind an HTTP(S) Load Balancer. Traffic flow:
Internet
|
v
Google Front End (GFE) — DDoS absorption at network edge
|
v
Cloud Armor Security Policy — WAF rules evaluated here
| (matched rules: allow, deny, or throttle)
v
Load Balancer Backend Service
|
v
Your Application (Cloud Run, GKE, GCE)
Requests that match a deny rule in Cloud Armor never reach your backend. This is the key cost and availability benefit.
Setting Up a Security Policy
# Create the base security policy
gcloud compute security-policies create production-waf --description="Production WAF for public applications" --type=CLOUD_ARMOR
# Attach to your backend service
gcloud compute backend-services update my-backend --global --security-policy=production-waf
OWASP ModSecurity Core Rule Set
Cloud Armor includes pre-configured rules that implement the OWASP ModSecurity CRS. These rules detect the most common web attack patterns without requiring you to write regex from scratch.
# Enable OWASP CRS rule groups
# Each rule group targets a specific attack category
# SQL injection protection (priority 1000)
gcloud compute security-policies rules create 1000 --security-policy=production-waf --description="OWASP SQLi protection" --expression="evaluatePreconfiguredExpr('sqli-v33-stable')" --action=deny-403 --preview # Start in preview mode — log but don't block
# XSS protection (priority 1001)
gcloud compute security-policies rules create 1001 --security-policy=production-waf --description="OWASP XSS protection" --expression="evaluatePreconfiguredExpr('xss-v33-stable')" --action=deny-403 --preview
# Remote code execution protection (priority 1002)
gcloud compute security-policies rules create 1002 --security-policy=production-waf --description="OWASP RCE protection" --expression="evaluatePreconfiguredExpr('rce-v33-stable')" --action=deny-403 --preview
# Local file inclusion protection (priority 1003)
gcloud compute security-policies rules create 1003 --security-policy=production-waf --description="OWASP LFI protection" --expression="evaluatePreconfiguredExpr('lfi-v33-stable')" --action=deny-403 --preview
# Scanner detection (priority 1004)
gcloud compute security-policies rules create 1004 --security-policy=production-waf --description="Block security scanners" --expression="evaluatePreconfiguredExpr('scannerdetection-v33-stable')" --action=deny-403 --preview
Moving from Preview to Enforcement
Run in preview mode for 1-2 weeks and analyze logs before enforcing:
# Query Cloud Armor preview logs
gcloud logging read 'resource.type="http_load_balancer" AND jsonPayload.enforcedSecurityPolicy.name="production-waf" AND jsonPayload.enforcedSecurityPolicy.outcome="PREVIEW"' --freshness=7d --format=json | jq '[.[] | {
rule: .jsonPayload.previewSecurityPolicy.name,
matched_expression: .jsonPayload.previewSecurityPolicy.matchedFieldValuesInExpression,
url: .jsonPayload.httpRequest.requestUrl,
ip: .jsonPayload.httpRequest.remoteIp
}]'
Review the matched requests. For each preview hit:
- If it's a genuine attack attempt (SQL injection probe, XSS payload) — enable enforcement
- If it's a false positive from your own application or a trusted API partner — add a higher-priority allow rule
# Remove --preview to enforce a rule
gcloud compute security-policies rules update 1000 --security-policy=production-waf --no-preview
# Add a higher-priority allow rule for known false positives
# Example: Your internal API testing tool triggers SQLi rules
gcloud compute security-policies rules create 100 --security-policy=production-waf --description="Allow internal API testing" --expression="inIpRange(origin.ip, '10.0.0.0/8')" --action=allow
Rate Limiting: Protecting Against Bots and Credential Stuffing
Rate limiting throttles or blocks IPs that exceed request thresholds:
# Global rate limit: max 1000 requests per minute per IP
gcloud compute security-policies rules create 2000 --security-policy=production-waf --description="Global rate limit" --action=throttle --rate-limit-threshold-count=1000 --rate-limit-threshold-interval-sec=60 --conform-action=allow --exceed-action=deny-429 --enforce-on-key=IP --src-ip-ranges="*"
# Strict rate limit on login endpoint: max 10 attempts per minute per IP
gcloud compute security-policies rules create 500 --security-policy=production-waf --description="Login rate limit" --expression="request.path.matches('/api/auth/login')" --action=throttle --rate-limit-threshold-count=10 --rate-limit-threshold-interval-sec=60 --conform-action=allow --exceed-action=deny-429 --enforce-on-key=IP --ban-duration-sec=300 # Ban IP for 5 minutes after exceeding
# Rate limit on password reset: max 3 requests per 15 minutes
gcloud compute security-policies rules create 501 --security-policy=production-waf --description="Password reset rate limit" --expression="request.path.matches('/api/auth/forgot-password')" --action=throttle --rate-limit-threshold-count=3 --rate-limit-threshold-interval-sec=900 --conform-action=allow --exceed-action=deny-429 --enforce-on-key=IP
Geo-Blocking for Compliance and Risk Reduction
Block traffic from specific regions where your application doesn't operate and has high attack traffic:
# Block traffic from countries where you have no legitimate users
gcloud compute security-policies rules create 3000 --security-policy=production-waf --description="Geo-restriction" --expression="origin.region_code == 'KP' || origin.region_code == 'IR' || origin.region_code == 'SY'" --action=deny-403
# Allow only European traffic (for GDPR-compliant EU-only services)
gcloud compute security-policies rules create 3001 --security-policy=production-waf --description="EU-only access" --expression="!( origin.region_code == 'DE' || origin.region_code == 'NL' || origin.region_code == 'FR' || origin.region_code == 'GB' || origin.region_code == 'BE' )" --action=deny-403
Adaptive Protection: Automated DDoS Detection
Cloud Armor Adaptive Protection uses machine learning to detect and automatically suggest mitigation rules for DDoS attacks in real time.
# Enable Adaptive Protection on your security policy
gcloud compute security-policies update production-waf --enable-layer7-ddos-defense
# Configure Adaptive Protection threshold
gcloud compute security-policies update production-waf --layer7-ddos-defense-rule-visibility=STANDARD
When Adaptive Protection detects an attack, it:
- Creates a suggested rule in the Cloud Armor console
- Sends an alert to Cloud Monitoring
- Optionally auto-deploys the rule (if configured)
Configure alerting for Adaptive Protection events:
gcloud alpha monitoring policies create --display-name="Cloud Armor Adaptive Protection Alert" --condition-filter='resource.type="network_security_policy" AND metric.type="networksecurity.googleapis.com/https/adaptive_protection/detected_attack_count"' --condition-threshold-value=1 --condition-threshold-comparison=COMPARISON_GT --notification-channels=$CHANNEL_ID
Bot Management
For e-commerce and high-value applications, add bot detection:
# Enable reCAPTCHA Enterprise integration
gcloud compute security-policies update production-waf --recaptcha-redirect-site-key=YOUR_RECAPTCHA_SITE_KEY
# Challenge suspicious traffic with reCAPTCHA
gcloud compute security-policies rules create 4000 --security-policy=production-waf --description="Challenge suspicious bot behavior" --expression="request.path.matches('/checkout|/api/order')" --action=redirect --redirect-type=GOOGLE_RECAPTCHA
Monitoring Cloud Armor Effectiveness
# Daily Cloud Armor effectiveness report
gcloud logging read 'resource.type="http_load_balancer" AND jsonPayload.enforcedSecurityPolicy.name="production-waf"' --freshness=24h --format=json | jq '
[.[] | .jsonPayload.enforcedSecurityPolicy] |
group_by(.configuredAction) |
map({action: .[0].configuredAction, count: length})
'
Key metrics to track weekly:
- Blocked requests by rule: Are the WAF rules blocking real attacks or generating false positives?
- Requests per country: Validate geo-blocking effectiveness
- Rate limit hits: Identify persistent bot IPs to add to permanent blocklist
- Adaptive Protection events: Review suggested rules and deploy if appropriate
For securing your serverless and GKE workloads behind Cloud Armor, see our GCP serverless security guide and GKE security hardening guide.