Filter rules define when and how the WAF should block requests and ban IP addresses. Rules are configured in the jailManager.filterRules section.
The WAF supports three types of rules:
- Static Rules - Block IPs from external lists
- Flexible Rules - Block based on request properties
- Composite Rules - Rate limiting with configurable thresholds
All rules share these common fields:
jailManager:
filterRules:
- name: unique-rule-name
type: static | flexible | composite
# Type-specific fields...- name: Unique identifier for the rule (used in logs, metrics, ban metadata)
- type: Rule type (
static,flexible, orcomposite)
Block IPs from an external JSON list loaded via URL.
Use cases:
- Third-party threat intelligence feeds
- Centrally managed blocklists
- Shared blocklists across multiple WAF instances
Configuration:
- name: static-blacklist-feed
type: static
linkUrl: "https://example.com/blocklist.json"
updateInterval: 60000 # millisecondsFields:
- linkUrl: URL to a JSON file containing array of IP addresses
- updateInterval: How often to refresh the list (in milliseconds)
Expected JSON format:
[
"1.2.3.4",
"5.6.7.8",
"192.168.1.0/24"
]Example:
- name: abuse-ip-db
type: static
linkUrl: "https://api.abuseipdb.com/api/v2/blacklist"
updateInterval: 3600000 # Update hourlyBehavior: If a request comes from an IP in the list, it's immediately blocked. The IP is NOT added to the jail (these are pre-existing blocks).
Block requests based on matching specific properties (URL, User-Agent, country, etc.).
Use cases:
- Block specific user agents (bots, scrapers)
- Block access to admin pages from foreign countries
- Block specific HTTP methods
- Block based on custom headers
Configuration:
- name: block-bad-bots
type: flexible
conditions:
- field: user-agent
check:
- method: equals
values:
- "bot"
- "scraper"
- "crawler"Fields:
- conditions: Array of conditions that must ALL match (AND logic)
Condition Fields:
- field: Request property to check (see Available Fields)
- check: Array of check methods and values
- method: Comparison method (see Comparison Methods)
- values: Array of values to compare against
Available Fields:
ip- Client IP addresscountry- Client country code (e.g., "US", "GB")city- Client city name (e.g., "London", "New York")url- Request URL path (e.g., "/api/users")user-agent- User-Agent header valuemethod- HTTP method (GET, POST, etc.)header:<name>- Custom header value (e.g.,header:x-api-key)
Comparison Methods:
equals- Exact matchregexp- Regular expression match
Examples:
Block access to /admin from non-US countries:
- name: admin-geo-block
type: flexible
conditions:
- field: url
check:
- method: equals
values: ["/admin"]
- field: country
check:
- method: equals
values: ["US", "GB"]Block specific user agents:
- name: block-scrapers
type: flexible
conditions:
- field: user-agent
check:
- method: regexp
values: ["(bot|crawler|spider|scraper)"]Block POST to sensitive endpoints:
- name: block-post-to-config
type: flexible
conditions:
- field: method
check:
- method: equals
values: ["POST"]
- field: url
check:
- method: equals
values: ["/config", "/settings"]Behavior: Requests matching ALL conditions are immediately blocked. The IP is NOT added to the jail.
Rate limiting with request counting and threshold-based banning.
Use cases:
- Prevent brute force attacks (login, API)
- Rate limit API endpoints
- Prevent scraping/crawling
- Mitigate DDoS attacks
- Protect against credential stuffing
Configuration:
- name: api-rate-limit
type: composite
uniqueClientKey: ["ip"]
conditions: []
limit: 100
period: 60
duration: 300
escalationRate: 1.5Fields:
- uniqueClientKey: Fields to group requests by (see Grouping Keys)
- conditions: Optional conditions to narrow the scope (same as Flexible rules)
- limit: Maximum requests allowed within the period
- period: Time window in seconds
- duration: Ban duration in seconds when limit is exceeded
- escalationRate: Multiplier for repeat offenses (1.0 = no escalation)
Grouping Keys:
Keys determine how requests are counted. Multiple keys create unique combinations.
Available keys:
ip- Count per IP addresscountry- Count per countrycity- Count per cityurl- Count per URLuser-agent- Count per User-Agentmethod- Count per HTTP methodheader:<name>- Count per custom header value
Examples:
Simple IP-based rate limit:
- name: global-rate-limit
type: composite
uniqueClientKey: ["ip"]
conditions: []
limit: 1000
period: 60 # 1000 requests per 60 seconds
duration: 300 # Ban for 5 minutes
escalationRate: 1.5Login brute force protection:
- name: login-bruteforce
type: composite
uniqueClientKey: ["ip"]
conditions:
- field: url
check:
- method: equals
values: ["/api/login", "/auth/login"]
- field: method
check:
- method: equals
values: ["POST"]
limit: 5
period: 300 # 5 login attempts per 5 minutes
duration: 900 # Ban for 15 minutes
escalationRate: 2.0API endpoint protection per IP:
- name: api-per-endpoint-limit
type: composite
uniqueClientKey: ["ip", "url"] # Separate limits per IP+URL combination
conditions:
- field: url
check:
- method: regexp
values: ["^/api/"]
limit: 100
period: 60
duration: 600
escalationRate: 1.5Strict country-based limit:
- name: risky-country-limit
type: composite
uniqueClientKey: ["ip"]
conditions:
- field: country
check:
- method: equals
values: ["CN", "RU"]
limit: 10
period: 60
duration: 3600
escalationRate: 3.0Behavior:
- Requests matching conditions are counted per uniqueClientKey combination
- When limit is exceeded within period, IP is added to jail
- Subsequent violations increase ban time via escalation
Rules are evaluated in this order:
- Whitelist (if configured) - Bypasses all rules
- Blacklist (if configured) - Immediately blocks
- Static rules - Blocks from external lists
- Jail check - Blocks if IP is already banned
- Flexible rules - Blocks based on conditions
- Composite rules - Counts requests and bans if limit exceeded
Rules within each type are evaluated in the order defined in configuration.
jailManager:
enabled: true
storage:
driver: file
driverConfig:
filePath: './data/blocked_ips.json'
filterRules:
# External threat feed
- name: threat-intelligence
type: static
linkUrl: "https://feeds.example.com/malicious-ips.json"
updateInterval: 3600000
# Block bad bots
- name: block-bots
type: flexible
conditions:
- field: user-agent
check:
- method: regexp
values: ["(bot|crawler|scraper|spider)"]
# Admin access - US only
- name: admin-geo-block
type: flexible
conditions:
- field: url
check:
- method: equals
values: ["/admin", "/wp-admin"]
- field: country
check:
- method: equals
values: ["US"]
# Login brute force protection
- name: login-protection
type: composite
uniqueClientKey: ["ip"]
conditions:
- field: url
check:
- method: regexp
values: ["/(login|auth)"]
- field: method
check:
- method: equals
values: ["POST"]
limit: 5
period: 300
duration: 900
escalationRate: 2.0
# API rate limiting
- name: api-rate-limit
type: composite
uniqueClientKey: ["ip", "url"]
conditions:
- field: url
check:
- method: regexp
values: ["^/api/"]
limit: 100
period: 60
duration: 300
escalationRate: 1.5
# Global rate limit
- name: global-rate-limit
type: composite
uniqueClientKey: ["ip"]
conditions: []
limit: 10000
period: 3600
duration: 600
escalationRate: 1.2Always test new rules in audit mode first:
wafMiddleware:
mode: auditIn audit mode:
- Rules are evaluated
- Violations are logged
- No requests are blocked
- No IPs are banned
Review logs to see which rules are triggered:
[INFO] Rule 'login-protection' triggered for IP 1.2.3.4
[INFO] Would ban IP 1.2.3.4 for 900 seconds (audit mode)
Ensure legitimate traffic isn't being flagged.
Once satisfied, switch to normal mode:
wafMiddleware:
mode: normal- Start with audit mode - Test rules before enforcement
- Use specific conditions - Avoid overly broad rules
- Whitelist trusted sources - Prevent accidental blocks
- Monitor metrics - Track rule effectiveness
- Use escalation - Progressive punishment for repeat offenders
- Combine rule types - Layer defenses (static + flexible + composite)
- Regular review - Update rules based on attack patterns
- Document rules - Use descriptive names and comments
- name: login-bruteforce-protection
type: composite
uniqueClientKey: ["ip"]
conditions:
- field: url
check:
- method: equals
values: ["/api/auth/login"]
limit: 5
period: 300
duration: 1800
escalationRate: 2.0# Block non-whitelisted countries
- name: admin-geo-fence
type: flexible
conditions:
- field: url
check:
- method: equals
values: ["/admin"]
- field: country
check:
- method: equals
values: ["US", "GB"]
# Rate limit admin access
- name: admin-rate-limit
type: composite
uniqueClientKey: ["ip"]
conditions:
- field: url
check:
- method: equals
values: ["/admin"]
limit: 50
period: 60
duration: 600
escalationRate: 2.0# Per-endpoint limits
- name: api-per-endpoint
type: composite
uniqueClientKey: ["ip", "url"]
conditions:
- field: url
check:
- method: regexp
values: ["^/api/"]
limit: 100
period: 60
duration: 300
escalationRate: 1.5
# Global API limit
- name: api-global
type: composite
uniqueClientKey: ["ip"]
conditions:
- field: url
check:
- method: regexp
values: ["^/api/"]
limit: 1000
period: 60
duration: 600
escalationRate: 1.3- Verify conditions match actual requests
- Check rule order (earlier rules may block first)
- Enable debug logging in application settings
- Add more specific conditions
- Increase limit/period for composite rules
- Whitelist legitimate users/IPs
- Review logs in audit mode
- Decrease limit for composite rules
- Add more restrictive conditions
- Combine multiple rule types
- Jail System - Ban storage and management
- Ban Escalation - Understanding escalation
- Static Lists - Whitelist/Blacklist
- Use Cases - Practical scenarios