WAF Firewall

Block malicious traffic at the edge with the Web Application Firewall.


Overview

The WAF (Web Application Firewall) lets you control who can access your content by creating rules based on IP addresses, countries, or paths. Rules are evaluated at the edge, blocking threats before they reach your origin.


Rule Types

IP-Based Rules

Block or allow specific IP addresses or CIDR ranges:

192.168.1.1       # Single IP
10.0.0.0/8        # CIDR range
203.0.113.0/24    # /24 subnet

Country-Based Rules

Block or allow entire countries using ISO country codes:

CN    # China
RU    # Russia
US    # United States
DE    # Germany

Country detection uses MaxMind GeoIP2 database.


Actions

Block

Immediately returns a 403 Forbidden response with a styled error page.

Best for:

  • Known malicious IPs
  • Banned countries
  • Blocked bots

Allow

Immediately allows the request, skipping all subsequent rules.

Best for:

  • Whitelisting trusted IPs (office, monitoring)
  • Allowing specific countries
  • VIP access

Challenge

Shows a proof-of-work challenge page. The visitor's browser must complete a computation before accessing the site.

Best for:

  • Suspected bot traffic
  • High-risk regions
  • Rate limiting without blocking legitimate users

Rule Priority

Rules are evaluated in priority order (lowest number = highest priority).

Priority 1: Allow office IP (192.168.1.100)
Priority 2: Block country (CN)
Priority 3: Challenge country (RU)

First matching rule wins. In the example above:

  • Office IP is always allowed
  • China is blocked
  • Russia gets a challenge
  • Everyone else is allowed (no rule matches)

Creating Rules

From Dashboard

  1. Go to your zone settings
  2. Click "Firewall" tab
  3. Click "Add Rule"
  4. Configure:
    • Name (for your reference)
    • Priority (1-10000)
    • Target type (IP or Country)
    • IPs or countries
    • Action (Block, Allow, Challenge)
  5. Save the rule

Via API

curl -X POST "https://nordiccdn.com/api/v1/zones/{uuid}/waf-rules" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Block bad IPs",
    "priority": 100,
    "target_type": "ip",
    "ip_addresses": ["203.0.113.0/24", "198.51.100.1"],
    "action": "block"
  }'

Path Matching

Optionally restrict rules to specific paths:

Prefix Mode

/wp-admin/*     # All admin paths
/api/*          # All API paths
/downloads/*    # Download section

Regex Mode

^/wp-(admin|login).*    # Admin and login
\.(php|asp)$            # PHP and ASP files

Challenge Mode

When using the Challenge action:

Invisible Mode

  • Challenge runs automatically in background
  • Minimal visual interruption
  • User sees brief loading indicator
  • Best for light traffic filtering

Interactive Mode

  • Shows progress bar with solving percentage
  • User sees the challenge happening
  • Useful for aggressive filtering
  • Demonstrates security to visitors

Difficulty

Controls how long the challenge takes:

Difficulty Approximate Time
14 (Low) < 1 second
18 (Medium) 2-3 seconds
22 (High) 5-10 seconds
24 (Very High) 10-30 seconds

Cookie TTL

How long the challenge cookie is valid:

  • 1 hour (3600) - High security
  • 24 hours (86400) - Balanced (default)
  • 7 days (604800) - Low friction

Common Configurations

Block Known Bad Countries

{
  "name": "Block high-risk countries",
  "priority": 100,
  "target_type": "country",
  "countries": ["CN", "RU", "KP", "IR"],
  "action": "block"
}

Whitelist Office

{
  "name": "Allow office",
  "priority": 1,
  "target_type": "ip",
  "ip_addresses": ["203.0.113.10"],
  "action": "allow"
}

Protect Admin Area

{
  "name": "Challenge admin access",
  "priority": 50,
  "target_type": "country",
  "countries": ["*"],
  "paths": ["/wp-admin/*", "/wp-login.php"],
  "action": "challenge",
  "challenge_mode": "interactive",
  "challenge_difficulty": 18
}

Allow Only Specific Countries

[
  {
    "name": "Allow EU only",
    "priority": 1,
    "target_type": "country",
    "countries": ["DE", "FR", "NL", "DK", "SE", "NO", "FI"],
    "action": "allow"
  },
  {
    "name": "Block everyone else",
    "priority": 2,
    "target_type": "ip",
    "ip_addresses": ["0.0.0.0/0"],
    "action": "block"
  }
]

Monitoring

Rule Statistics

View rule performance in your dashboard:

  • Hits Total - How many times the rule matched
  • Last Hit - When the rule last triggered

Access Logs

Check access logs for blocked requests:

403 - Blocked by WAF rule "Block bad IPs"

Best Practices

1. Whitelist First

Always create allow rules for trusted IPs before block rules.

2. Use Challenges Before Blocking

For uncertain traffic, use challenges instead of blocks. This reduces false positives.

3. Monitor New Rules

After creating rules, monitor:

  • Legitimate traffic being blocked
  • Rule hit counts
  • Origin load changes

4. Regular Review

Review and update rules periodically:

  • Remove old office IPs
  • Update based on traffic patterns
  • Adjust difficulty based on bot activity

Troubleshooting

Legitimate Users Blocked

  1. Check rule priority order
  2. Add their IP to an allow rule
  3. Consider using challenge instead of block

Challenge Not Working

  1. Verify JavaScript is enabled
  2. Check for browser extensions blocking scripts
  3. Test in incognito mode

Country Detection Wrong

GeoIP databases occasionally have inaccuracies. Contact support if you notice consistent misdetection.