guard/src/config/sections/detect.rs
loki5512344 aa615a1141
fix: XDP unsafe loader + Redis sync; enforce 250-line/4-file layout limits
- xdp: CString for if_nametoindex (was UB), real detach via prog fd
  (fabricated borrow_raw(-1) silently never detached), SAFETY comments,
  saturating expiry math; +5 unit tests
- redis: real pubsub reconnect with exponential backoff (was sleep+return);
  KEYS -> SCAN in heartbeat sweep
- ci: cargo test --all-features, repo-gates job — module size gate
  (scripts/check_module_size.sh, ratchet baseline) + default-secrets grep
- refactor src/ to <=250 LOC/file, <=4 .rs/dir without behavior change;
  thin bins (rampart.rs 330 -> 6 LOC), new app/, subnet/, intel/,
  profile/, prefix/, challenge/, filter/, probe/, inventory/, metrics/, node/
- docs: TODO v5.0 (status refresh, new rules, findings backlog),
  README quickstart now matches real binaries
- verify: fmt/clippy -D warnings/test --all-features (164 tests)/clang XDP green
2026-09-15 23:55:17 +02:00

121 lines
3.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use serde::Deserialize;
/// Секция `[detect]`: детекторы распределённых атак.
#[derive(Debug, Clone, Default, Deserialize)]
pub struct DetectConfig {
#[serde(default)]
pub prefix: DetectPrefixConfig,
#[serde(default)]
pub autoban: DetectAutobanConfig,
#[serde(default)]
pub alert: DetectAlertConfig,
}
/// Секция `[detect.autoban]`: авто-бан источников по репутации и сигналам
/// детектора атак. Порог сравнивается со скором [`crate::traffic::reputation::IpReputation`],
/// TTL берётся из `ban.ban_duration_secs`.
#[derive(Debug, Clone, Deserialize)]
pub struct DetectAutobanConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default = "default_autoban_reputation_threshold")]
pub reputation_threshold: i32,
}
impl Default for DetectAutobanConfig {
fn default() -> Self {
Self {
enabled: false,
reputation_threshold: default_autoban_reputation_threshold(),
}
}
}
fn default_autoban_reputation_threshold() -> i32 {
-50
}
/// Секция `[detect.alert]`: webhook-алерты на переходах состояния атаки
/// («атака началась» / «атака закончилась»).
#[derive(Debug, Clone, Default, Deserialize)]
pub struct DetectAlertConfig {
#[serde(default)]
pub webhook_url: Option<String>,
}
/// Секция `[detect.prefix]`: subnet-level детектор распределённых атак.
#[derive(Debug, Clone, Deserialize)]
pub struct DetectPrefixConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default = "default_prefix_syn_threshold")]
pub syn_threshold: u64,
#[serde(default = "default_prefix_window_secs")]
pub window_secs: u64,
#[serde(default = "default_prefix_min_unique_sources")]
pub min_unique_sources: u64,
}
impl Default for DetectPrefixConfig {
fn default() -> Self {
Self {
enabled: false,
syn_threshold: default_prefix_syn_threshold(),
window_secs: default_prefix_window_secs(),
min_unique_sources: default_prefix_min_unique_sources(),
}
}
}
fn default_prefix_syn_threshold() -> u64 {
500
}
fn default_prefix_window_secs() -> u64 {
10
}
fn default_prefix_min_unique_sources() -> u64 {
16
}
/// Секция `[protocol]`: протокольные обработчики (plugin-by-feature).
#[cfg(feature = "protocol-http")]
#[derive(Debug, Clone, Default, Deserialize)]
pub struct ProtocolConfig {
#[serde(default)]
pub http: HttpProtocolConfig,
}
/// Секция `[protocol.http]`: политика HTTP/1.1-обработчика на edge-ноде.
#[cfg(feature = "protocol-http")]
#[derive(Debug, Clone, Deserialize)]
pub struct HttpProtocolConfig {
#[serde(default = "default_http_max_header_bytes")]
pub max_header_bytes: usize,
#[serde(default = "default_http_timeout_secs")]
pub timeout_secs: u64,
#[serde(default)]
pub blocked_paths: Vec<String>,
#[serde(default)]
pub require_user_agent: bool,
}
#[cfg(feature = "protocol-http")]
impl Default for HttpProtocolConfig {
fn default() -> Self {
Self {
max_header_bytes: default_http_max_header_bytes(),
timeout_secs: default_http_timeout_secs(),
blocked_paths: Vec::new(),
require_user_agent: false,
}
}
}
#[cfg(feature = "protocol-http")]
fn default_http_max_header_bytes() -> usize {
8192
}
#[cfg(feature = "protocol-http")]
fn default_http_timeout_secs() -> u64 {
5
}