Rules Engine
Motor de regras determinístico WAF-style — fast path antes de heurísticas e IA
Rules Engine
O Sentry tem um motor de regras determinístico que roda antes das
heurísticas e da IA — é o "fast path" do
Pipeline::process.
Inspirado nas Custom Rules / WAF da Cloudflare: cada regra é um match +
action, avaliada em ordem de prioridade crescente, com short-circuit.
Regras são a primeira linha de defesa (bloqueio instantâneo de scanners,
Tor, VPN/proxy, países) e também a fonte de allowlists (IPs/ASNs
confiáveis que bypassam todo o scoring).
Semântica de avaliação
O RuleSet
mantém as regras ordenadas por priority (menor = avalia primeiro) e
evaluate_with
retorna o primeiro match. O que acontece depende da
RuleAction:
| Action | Efeito |
|---|---|
Allow | Short-circuit: bypass total de scoring e IA (allowlist). |
Block / Challenge / RateLimit | Short-circuit: executa a contenção e encerra o pipeline. |
Log | Anota o evento (RuleHit peso 0) e continua para heurísticas + IA. |
Tag | Idem Log: anota e deixa fluir. |
Ordem resumida:
Evento normalizado
└─ Rules Engine (por prioridade; primeiro match vence)
├─ Allow → Allow + bypass de scoring/AI
├─ Block/Challenge/RateLimit → contenção imediata (short-circuit)
├─ Log/Tag → anota e continua
└─ nenhum match → heurísticas → reputation → routes
→ scorer → policy → deciderUm short-circuit de Block/Challenge/RateLimit gera um sinal
RuleHit
com peso fixo por verdict (Block 100, Challenge 50, RateLimit 30) e respeita
a guard de never-ban ([real_ip] trusted_ips) e o flag
cap_shadow
— IPs em shadow-list são analisados mas nunca banidos. A verbosidade no
console do evento short-circuitado é controlada por log_level na regra
(silent suprime a linha; o evento continua sendo armazenado e despachado).
Tipos principais
Definidos em
crates/sentry-core/src/rules.rs.
Rule — uma regra individual:
pub struct Rule {
pub id: RuleId,
pub name: String,
pub priority: i32,
pub enabled: bool,
pub match_: RuleMatch,
pub action: RuleAction,
pub ttl: Option<Duration>,
pub source: RuleSource,
pub tags: Vec<String>,
pub log_level: Option<RuleLogLevel>,
}ttlexpira regras dinâmicas (blocks temporários; o reaper do Cloudflare usa o mesmo formatosentry:<ts>:<ttl>).log_levelcontrola a verbosidade da linha no console (silent,info,warn,error).- O id de regras de config é um slug ASCII estável do nome
(
allow_internal_monitoring).
RuleAction — Allow | Block | Challenge | RateLimit | Log | Tag.
RuleSource — origem da regra:
| Variante | Origem |
|---|---|
Config | [[rules.custom]] no sentry.toml. |
Db | Criada via CLI/dashboard, persistida no Postgres. |
CloudflareSync | Espelho de regras vivas do edge Cloudflare (reconcile no startup). |
Feed | Gerada pelo importador de reputation feeds/datasets (feed:<name>). |
AutoLearned | Auto-block com TTL derivado de incidentes confirmados. |
DefaultPack | Pack default embutido. |
RuleMatch — a condição (árvore combinável All/Any/Not).
A referência completa das condições e da sintaxe textual está na página
DSL de Match.
RuleSet — conjunto compilado e ordenado por prioridade, com
replace_by_prefix
para troca atômica de grupos de regras (usado no hot-reload de datasets).
SharedRuleSet — alias Arc<RwLock<RuleSet>>
(definição):
o daemon compartilha o mesmo handle com pipeline, edge inline e CLI; o
hot-reload troca o conjunto interno com write() e a avaliação lê com
read().
Fontes de regras
- Config (
sentry.toml) —[[rules.custom]]compiladas porrules_from_config: uma expressão DSL inválida derruba só aquela regra (com o nome no erro), não o config inteiro. - Postgres (tabela
rules) — regras dinâmicas criadas via CLI (sentry rules add/allow/block) ou dashboard. - Packs default — ver Default Rule Packs.
- Reputation feeds e datasets — regras sintéticas
feed:<name>(prioridade 50) geradas porfeed_rule(IP, quando a feed declaraaction) edataset_rule(user_agent/path/ja3). - Cloudflare sync — o reconcile do startup adota regras vivas do edge
como espelho local (
CloudflareSync). - Auto-learned — escalada de reincidentes persistida no
ip_state.
Hot-reload
sentry_rules_changed— taskrules_hot_reloadfazLISTENno canal Postgres, recarrega o ruleset do banco e troca oArc<RwLock<RuleSet>>sem restart. CLI/dashboard emitem oNOTIFY.sentry_datasets_changed— taskdatasets_hot_reloadreconstrói as regras com prefixodataset:viareplace_by_prefix(troca atômica, all-or-nothing) e atualiza os literais do prefilter.- O Postgres é a fonte da verdade: um nó que sobe depois carrega o ruleset do banco no startup.
Caches de performance (F5)
- Cache de regex
(
REGEX_CACHE) e cache de IP-spec (IP_CACHE) de processo: padrões compilados 1× (o código antigo compilava regex por regra por evento — ~3,4 ms/evento). Patterns inválidos são cacheados comoNonepara não re-parsear por evento. - Prefilter Aho-Corasick — as heurísticas só rodam a regex da família
quando um literal aparece no texto
(
PREFILTER, umArcSwap); datasetsuser_agent/pathentram nesse gate viareload_dataset_lists, junto comSENSITIVE_PATH_REeBAD_CRAWLER_RE. - Decode-once — o path URL-decodificado é computado 1× por avaliação
(
EvalCtx) e compartilhado por todas as condiçõespath; regras nunca são burladas por encoding (%2e%2e%2f=../,+= espaço —url_decode).
Empacotamento de config
Packs default são declarados assim:
[[rules.pack]]
name = "vpn_proxy"
mode = "shadow" # shadow | enforce | off
[[rules.pack]]
name = "country_blocklist"
mode = "enforce"
[rules.pack.params]
countries = ["RU", "CN"]Cada pack vira um par de chaves no mapa de modos e cada param é achatado
como <pack>__<param> (ex.: country_blocklist__countries) antes de ir ao
builder —
wiring no daemon.
Esse achatamento (F7.6) corrigiu o bug em que params de pack nunca chegavam
ao builder. Só valores string e arrays de string são renderizados. Os
params lidos hoje são country_blocklist__countries e
host_allowlist__domains
(pack_list_param).
CLI de gestão de regras
sentry rules list # lista regras ativas
sentry rules show <id>
sentry rules add --name "block admin from RU" \
--match 'country=RU AND path=/admin/*' --action block --priority 10
sentry rules allow <ip> [--ttl 24h] [--note "monitoring agent"]
sentry rules block <ip> [--ttl 24h] [--note "scan"]
sentry rules enable <id> | disable <id> | delete <id>
sentry rules packs # estado dos packs default
sentry rules test --path /admin --method GET --ip 1.2.3.4 --ua "sqlmap/1.0"sentry rules test avalia a expressão de match contra um evento hipotético
— use para validar regras antes de promover para enforce. As ações
allow/block por IP gravam no Postgres e emitem NOTIFY, então nós em
execução recarregam sem restart.
Próximos passos
- DSL de Match — sintaxe completa das condições.
- Default Rule Packs — catálogo atual dos packs.
- Shadow vs Enforce — rollout seguro e política de verdicts.