Default Rule Packs
The current catalog of pre-configured packs shipped with Sentry
Default Rule Packs
Packs are sets of pre-built rules in
crates/sentry-core/src/packs.rs
that join the ruleset at startup. Each pack has a
PackMode:
shadow (log only), enforce (act) or off (rules not loaded). The
canonical list is
all_pack_names;
default modes come from
build_default_ruleset_with.
Overview
| Pack | Default | In shadow | In enforce | Priority | Params |
|---|---|---|---|---|---|
sensitive_paths | enforce | Log | Block | 5 | — |
host_allowlist | off | Log | Block | 8 | domains |
crawlers_bad | shadow | Log | Block | 10 | — |
country_blocklist | off | Log | Block | 10 | countries |
http_anomaly | shadow | Log | Block | 12 | — |
empty_ua | shadow | Log | Challenge | 15 | — |
rate_scan | shadow | Log | RateLimit | 15 | — |
vpn_proxy | shadow | Log | Challenge | 20 | — |
tor | shadow | Log | Block | 20 | — |
crawlers_good | off | Allow | Allow | 2–3 | — |
Notes:
sensitive_pathsis the only pack that ships inenforce— access to.env/.git/.sshis statistically always malicious.crawlers_goodproducesAllowrules in any active mode (the mode only turns the pack on/off); it ships off by default.- Unknown mode strings become
off(PackMode::parse). sentry rules packslists the current state of every pack.
sensitive_paths (default: enforce)
Single source of truth:
lists::SENSITIVE_PATHS
— the same table feeds the pack, the SensitivePath heuristic and the
Aho-Corasick prefilter literals. Each pattern becomes a case-insensitive
path regex rule (evaluated over the URL-decoded path).
Covered categories:
- Dotfiles and secrets —
/.env,/.git,/.svn,/.hg,/.bzr,/.ssh,/.aws,/.gcp,/.azure,/.kube,/.docker,/.terraform,/.npmrc,/.pypirc,/.netrc,/.htpasswd,/.DS_Store. - Admin panels —
wp-admin,wp-login.php,phpmyadmin,pma,adminer,wp-content,/manager/html(Tomcat),wp-includes/*.php. - Server status —
server-status,server-info,nginx-status,fpm-status. - Spring Boot —
/actuator/env,/actuator/heapdump,/actuator/threaddump. - Backups and artifacts — extensions
.sql,.bak,.backup,.old,.swp,.orig,.save. - Known CVE probes — Laravel
_ignition/execute-solution, PHPUniteval-stdin.php, ExchangeAutodiscover.xmland/ecp/current/exporttool, MobileIron/mifs/.;/services/logservice, TelerikWebResource.axd, GPON/gponform/diag_form,/restapi/logoncustomization,/hnap1, Fortinet/remote/fgt_lang.
The pack also ships an allow rule at priority 1 for
/.well-known/security.txt (RFC 9116), so the public
responsible-disclosure document is never blocked.
[[rules.pack]]
name = "sensitive_paths"
mode = "enforce" # default — drop to "shadow" if your site really serves these pathshost_allowlist (default: off)
Blocks requests whose Host header is not one of the configured
domains — including Host-less requests (bare-IP scans and IDN homograph
attempts). Implemented as NOT header.host regex ...
(host_allowlist_rules).
[[rules.pack]]
name = "host_allowlist"
mode = "enforce"
[rules.pack.params]
domains = ["example.com", "www.example.com"]crawlers_bad (default: shadow)
A single UA-regex rule
(bad_crawler_rules)
aggregating pentest tools and scanners (sqlmap, nikto, nmap,
masscan, zgrab, nessus, gobuster, ffuf, nuclei, wfuzz…),
script HTTP clients (python-requests, go-http-client, curl/…) and
aggressive SEO/data bots (semrush, ahrefs, mj12bot, bytespider…).
[[rules.pack]]
name = "crawlers_bad"
mode = "enforce"crawlers_good (default: off)
Allow rules by UA for legitimate bots
(good_crawler_rules).
With [bot_verification] enabled = true (F7.7) the pack splits in two:
crawlers_good_verified(priority 2) — rDNS-verifiable engines (Googlebot,Bingbot,Slurp,Baiduspider,YandexBot) with the extrabot_verified = "true"condition: a spoofed UA earns no allow.crawlers_good_unverified_ok(priority 3) — engines that cannot be verified via rDNS (DuckDuckBot,facebookexternalhit,Twitterbot,LinkedInBot,Applebot,Puppeteer,WhatsApp,TelegramBot,Discordbot,W3C_Validator,curl/8,Go-http-client/1.1) keep the plain UA allow.
Without bot verification the pack falls back to a single rule with the combined list.
[[rules.pack]]
name = "crawlers_good"
mode = "enforce" # action is always Allow — the mode only turns the pack onempty_ua (default: shadow)
Empty User-Agent (UserAgent equals "") → Challenge when enforced
(empty_ua_rules).
Rare in legitimate browser traffic.
http_anomaly (default: shadow)
Rare methods TRACE and CONNECT → Block when enforced
(http_anomaly_rules),
two priority-12 rules.
vpn_proxy (default: shadow)
reputation = "vpn" → Challenge when enforced
(vpn_proxy_rules).
Only works for real with an IP feed of tier vpn configured (presets
open_source_vpn_ips / anti_vpn) — without a feed the tier is never
assigned and the rule never fires.
tor (default: shadow)
reputation = "tor" → Block when enforced
(tor_rules).
Requires the tor_exit preset (or an equivalent feed) — without it, it
never fires.
rate_scan (default: shadow)
The rate_scan_404 rule
(rate_scan_rules):
status=404 AND rate 10/60s per_ip → RateLimit when enforced (directory
brute-force). The Status(404) filter is real — the rate window only
counts 404s. Requires the daemon's rate-limit backend.
country_blocklist (default: off)
country = <code> → Block when enforced, for the configured list
(country_blocklist_rules).
ISO 3166-1 alpha-2 codes, case-insensitive compare. Requires the
countries param — without it the pack generates no rules.
[[rules.pack]]
name = "country_blocklist"
mode = "enforce"
[rules.pack.params]
countries = ["RU", "CN", "KP"]Datasets and reputation feeds
Beyond the packs, [[rules.feeds]] generates synthetic feed:<name>
rules (priority 50, source Feed) via
feed_rule
and
dataset_rule:
kind | What it generates | Default action |
|---|---|---|
ip | Enrichment (ReputationStore longest-prefix) + a synthetic rule only if action is set | (no rule) |
user_agent | One UA rule — the whole list as a case-insensitive literal alternation (cap MAX_DATASET_ENTRIES = 5000) | log |
path | Same, over the path | log |
ja3 | RuleMatch::Ja3In — a hash set (TLS handshake events only) | log |
Fields: name, url (http/https with SSRF guard), kind, tier (ip
only; default malicious), action, refresh_hours (default 24),
headers_env (authenticated headers), enabled (default true).
[[rules.feeds]]
name = "spamhaus_drop"
url = "https://www.spamhaus.org/drop/drop.txt"
tier = "malicious"
refresh_hours = 24
action = "block" # without action: enrichment only (tor/vpn_proxy start working)
[[rules.feeds]]
name = "bad_bots_ultimate"
kind = "user_agent"
url = "https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list"
refresh_hours = 24
action = "log" # start in shadow; flip to "block" after auditing
[[rules.feeds]]
name = "probe_paths"
kind = "path"
url = "https://example.invalid/probe-paths.txt"
refresh_hours = 24
action = "challenge"
[[rules.feeds]]
name = "abuseipdb_blacklist"
url = "https://api.abuseipdb.com/api/v2/blacklist?confidenceMinimum=90&plaintext=true"
tier = "malicious"
refresh_hours = 24
headers_env = { Key = "SENTRY_ABUSEIPDB_KEY" }Presets — instead of hand-writing feeds,
[rules] feed_presets = ["tor_exit", "firehol_level1", "proxy_list", "open_source_vpn_ips", "anti_vpn"] enables curated public blocklists;
preset feeds block by default — enable one only if you accept banning
those ranges (e.g. VPN users).
DB-backed datasets (F7.7) — the Postgres equivalent of the
user_agent/path/ja3 feeds, no TOML needed:
sentry datasets import <file|url> --kind user_agent --name <name> [--action block],
plus list|enable|disable|delete|fetch. Rules get the dataset:<name> id and
are hot-reloaded (together with the prefilter literals) over the
sentry_datasets_changed channel. Use datasets for lists that change
without a deploy; use [[rules.feeds]] for lists versioned in config.