Rule Structure
A bot rule consists of matchers and an action:Required Fields
| Field | Type | Description |
|---|---|---|
name | string | Unique identifier for the rule |
action | string | Action to take: ALLOW, DENY, CHALLENGE, WEIGH |
Matchers
Rules must include at least one matcher:| Matcher | Type | Description |
|---|---|---|
user_agent_regex | regex string | Match User-Agent header |
path_regex | regex string | Match request path |
headers_regex | map[string]regex | Match arbitrary headers |
remote_addresses | []CIDR | Match client IP ranges |
expression | CEL expression | Advanced matching logic |
Matcher Types
User Agent Matching
Path Matching
Header Matching
IP Range Matching
Combined Matching
Combine IP ranges with other matchers:CEL Expressions
For advanced matching, use Common Expression Language (CEL) expressions:Single Expression
Multiple Conditions (all)
All conditions must be true:Multiple Conditions (any)
At least one condition must be true:Available Variables
| Variable | Type | Example |
|---|---|---|
remoteAddress | string | "1.2.3.4" |
userAgent | string | "Mozilla/5.0..." |
path | string | "/api/users" |
method | string | "GET", "POST" |
host | string | "example.com" |
headers | map[string]string | {"User-Agent": "..."} |
query | map[string]string | {"page": "1"} |
contentLength | int64 | 1024 |
load_1m | double | 2.5 (system load average) |
load_5m | double | 3.1 |
load_15m | double | 2.8 |
DNS Functions
reverseDNS(ip)- Get PTR recordslookupHost(hostname)- Get A/AAAA recordsverifyFCrDNS(ip)- Verify FCrDNSverifyFCrDNS(ip, pattern)- Verify FCrDNS with regex patternarpaReverseIP(ip)- Convert to ARPA notation
Helper Functions
Rule Actions
ALLOW
Bypass all checks and forward to backend:DENY
Block with a deceptive success page:CHALLENGE
Present a proof-of-work challenge:WEIGH
Adjust request suspicion score:Rule Evaluation Order
Rules are evaluated in the order they appear in the policy file. The first matching rule determines the action.Weight-Based Rules
Weight rules accumulate. All matching WEIGH rules apply:Regular Expression Syntax
Anubis uses Go’s regexp package (RE2 syntax):Common Patterns
Allow Static Assets
Block Known Bad Actors
Protect POST Endpoints
Dynamic Load Protection
Best Practices
- Order matters: Place specific ALLOW rules before generic DENY rules
- Test expressions: Use
--debug-benchmark-jsto test without blocking - Use FCrDNS: Verify bot IP addresses with
verifyFCrDNS() - Prefer CHALLENGE over DENY: Legitimate users can solve challenges
- Monitor metrics: Track rule matches via Prometheus metrics
- Use weights: Build gradual suspicion instead of binary decisions
Generating Rules from robots.txt
Anubis includes therobots2policy tool to automatically convert robots.txt files into Anubis policy rules.
Usage
Options
| Flag | Default | Description |
|---|---|---|
-input | (required) | Path to robots.txt file, URL, or - for stdin |
-output | stdout | Output file path or - for stdout |
-format | yaml | Output format: yaml or json |
-action | CHALLENGE | Default action for disallowed paths |
-deny-user-agents | DENY | Action for blocked user agents |
-name | robots-txt-policy | Name for the generated policy |
-crawl-delay-weight | 0 | Weight adjustment based on crawl-delay |
Example Output
Inputrobots.txt:
Next Steps
- Challenge Configuration - Configure proof-of-work settings
- Policy Configuration - Complete policy file structure