- 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
19 KiB
19 KiB
Rampart — Development TODO & Roadmap
Живой документ. Философия: KISS → DRY → SOLID → YAGNI.
v0.3.0-dev — big-bang редизайн: из Minecraft-специфичной защиты в универсальную L3/L4/L7 платформу сетевой защиты. MC-код, Java-плагины и dashboard удалены (доступны в git-истории до тега v0.2.0).
0. Принципы разработки
KISS
- Не добавляй абстракцию до третьего повторения.
- Функция ≤ 60 строк, файл ≤ 250 строк, ≤ 4 .rs-файлов на папку (жёсткий лимит;
больше — декомпозиция или группировка доменами с ре-экспортами в mod.rs).
Гейт:
scripts/check_module_size.sh+ ratchet-базлайн.module_size_baseline(легаси — WARN, новые нарушения — FAIL; после рефакторинга--update-baseline). - Не используй generics где хватит
&strиVec<u8>.
DRY
- Повтор > 2 раз → выноси, но лучше копипаста чем неправильная абстракция.
SOLID (Rust)
- S: один файл = одна ответственность
- O: расширяй через трейты (
ProtocolHandler,Filter,StateStore) - L:
dyn Filter— любая реализация без side effects - I: маленькие трейты вместо одного God-trait
- D: core зависит от trait-ов, не от Redis/ClickHouse напрямую
YAGNI
- Не пиши BGP до v0.6, WASM-плагины до стабилизации compile-time API.
- Не добавляй feature flag если фича не готова.
Rust-специфичные
unwrap()— только в main() и тестахunsafe— только в xdp/, комментарий// SAFETY:обязателенclone()осознанно, профилируй hot path- Блокирующие операции →
spawn_blocking - Логи:
tracing::info!/debug!/error! - Метрики: register один раз при старте, инкремент в hot path
1. Целевая структура (v0.3)
guard/
├── Cargo.toml # ОДИН пакет rampart, features = ["protocol-http", ...]
├── scripts/ # check_module_size.sh (гейт 250/4), check_default_secrets.sh
├── src/
│ ├── bin/{rampart, rampart-manager, rampart-cli, rampart-tui}.rs # тонкие, логика в lib
│ ├── app/ # thin-main: runtime wiring, services (spawn-циклы)
│ ├── engine/ # listener, tunnel; challenge/ (pow+difficulty), subnet/ (tracker+monitor)
│ ├── filter/ # blacklist, rate_limit, geo — trait Filter
│ ├── traffic/ # hook + prefix/ (key+stats) + intel/ (ewma,detector,reputation) + profile/ (profiler,alert)
│ ├── store/ # redis (+ trait StateStore)
│ ├── manager/ # api/ (+ api/inventory/), auth/, sync/
│ ├── cli/ # команды; commands/node/ (status,drain,emergency)
│ ├── config/ # config + sections/{edge,platform,detect}
│ ├── tui/ # app/state/ui + metrics/ (prometheus,fetch)
│ ├── protocol/ # trait ProtocolHandler + registry; http/ под фичей
│ └── xdp/ # filter/ (attach,maps), probe/ (diagnostics/,stats,metrics), globals, noop
├── xdp/
│ ├── core/ # universal_filter.c + maps/stats/config/common.h + prefix_stats/syn_challenge
│ └── hooks/hook_api.h # контракт подключаемых BPF-протокол-хуков
├── tests/ # интеграционные (вне гейта 4-файлов: cargo требует 1 файл = 1 бинарь)
└── docs/ # kb/ (knowledge base) + research/ + ops-доки
1a. Статус после редизайна (2026-08-24)
| Что | Статус |
|---|---|
| plugins/ velocity+paper, dashboard/ | ✅ удалены (git-история) |
crates/* → единый пакет rampart + src/bin |
✅ сделано |
| MC-код (handshake, death_code, varint, hostname-HMAC) | ✅ удалён полностью |
PoW как универсальный hashcash (engine/challenge.rs) |
✅ сохранён |
| XDP: universal L3/L4 фильтр + hooks API | ✅ код готов, clang build OK |
| IPv6 баг в XDP (daddr→saddr) | ✅ исправлен |
| Knowledge Base docs/kb (attacks, defense-levels, practice) | ✅ написана, двуязычная |
| README + architecture.md под новую концепцию | ✅ переписаны |
| cargo build / clippy -D warnings / test | ✅ зелёные |
2. Ближайшие задачи (v0.3)
Subnet-level detection (ботнет с ротацией IP) — ✅ готово (2026-08/09)
- XDP: карта
prefix_stats(LRU_HASH, ключ /24 v4 | /64 v6) — счётчики SYN/pps per-префикс (xdp/core/prefix_stats.h, трафик-слой: src/traffic/prefix/). - Detector: превышение порога префиксом при IP под лимитом → флаг подсети (src/traffic/intel/detector.rs, src/engine/subnet/).
- Мягкая эскалация: monitor → strict_limit → challenge → block (SubnetVerdict-лестница; блок /24 идёт через ban_cidr, не слепой hard-ban).
- Блок подсети через
blacklist_map(LPM trie) —XdpFilter::ban_cidr.
Движок без протоколов — сделать полезным — ✅ готово
- Первый протокол-плагин:
protocol-http— HTTP/1.1 request-head анализ (src/protocol/http/, tests/http_protocol.rs). - TCP-proxy режим: tunnel.rs + ProtocolHandler интегрированы в listener/app wiring.
- Fail-fast сообщение при пустом registry (
ProtocolRegistry::primary()).
Подключение мёртвого интеллекта (правило: «мёртвый код = баг») — ✅ готово
- Traffic Intel в hot path: AttackDetector/IpReputation → метрики + auto-ban (src/traffic/hook.rs, src/engine/tunnel.rs, src/app/services.rs).
- Blacklist:
clear_expired()по таймеру (src/app/). - RateLimiter: TTL-эвикция idle bucket'ов.
Безопасность — ✅ кроме ролей
- Rate limiter на login endpoint manager API (per-IP, tests в api/auth.rs).
- JWT: audience-валидация, secret ≥ 32 байт fail-fast (rampart-manager.rs).
- JWT-роли: сейчас единственный hardcoded
admin; RBAC-ролей нет — либо убрать поле, либо делать роли (решение отложить до второго потребителя). - Redis:
KEYS→SCAN(scan_options), pubsub-подписчик — честный reconnect с экспоненциальным backoff (src/store/redis.rs).
XDP
- Verifier-проверка на реальном ядре (live-тест 2026-09: два бага RST-challenge найдены и
исправлены,
d6bcae5). - Rust loader (
src/xdp/filter/): open/load/attach, patch глобалов G_* из config.toml (src/xdp/globals.rs), CString-safe if_nametoindex, реальный detach по fd прогрессы. - Ringbuf events → blacklist:
drain_events()сейчас только логирует debug; нужен матчинг события →ban_ip(перенести из «loader», боится ошибок в data path). - Smoke-test attach в CI (VM runner с CAP_BPF) + netns+veth харнесс — вывод №7 из конкурентного анализа, приоритет v0.4.
Документация
- docs/deployment.md, configuration.md, runbook.md — старых крейтов/MC не упоминают (grep чисто).
- docs/kb/README.md — индекс KB со ссылками.
- TUI (ratatui): live-метрики из Prometheus endpoint — готово (src/tui/,
564613b).
2a. Раунд 2026-09-15 — исправлено по итогам ревью
- unsafe-баги XDP-лоадера (src/xdp/filter/):
&str.as_ptr()без NUL вif_nametoindex→CString; фиктивныйborrow_raw(-1)-fd вunload()→ реальный detach по fd прогрессы с propagatable ошибкой;unsafe impl Sendполучил// SAFETY:;saturating_mulв expiry. +5 юнит-тестов. - Redis: fake-reconnect pubsub (sleep+return) → настоящий reconnect-loop с backoff;
KEYS→SCANв heartbeat. - CI:
cargo test --all-features(раньше тесты фич не гонялись); jobrepo-gates: гейт 250/4 + grep дефолтных секретов; Makefileciобновлён. - README: несуществующие
rampart-core/rampart config init→ реальные команды; таблица компонентов/плагинов приведена к коду (http готов, minecraft удалён, добавлен rampart-tui). - Рефакторинг под новые лимиты 250/4 без изменения поведения: app/, challenge/, subnet/, prefix/, intel/, profile/, commands/node/, api/inventory/, tui/metrics/, filter/, probe/; bin-файлы тонкие (rampart.rs: 330 → 6 строк).
Новые найденные проблемы (чинить в v0.4)
cargo check --no-default-featuresсломан исторически: manager/sync и store ссылаются на redis без#[cfg(feature = "store-redis")]— нарушение «features additive».src/app/runtime.rs: узкий#[allow(clippy::exit)]— паллиатив после переноса main-логики в lib; правильно — возвращать exit-код изrun()вместоprocess::exit.- IPv6-банов в XDP-putи нет (
ban_cidrbail'ит на v6) — IPv6-паритет (вывод №8).
3. Backlog
- protocol-gRPC plugin (после http)
- BPF hook #1 реальный: HTTP поверх XDP (rate-limit до userspace)
- GeoIP/ASN reputation (enum есть, реализации нет)
- Bloom filter для blacklist
- io_uring runtime (feature flag)
- ML anomaly detection (Isolation Forest)
- Fuzzing парсеров (
cargo-fuzz) - BGP Anycast (AS + /24)
3a. Бенчмарк-конкуренты: чем превзойти
Все репо склонированы в
ref/(gitignored). Анализ issues/PRs проведён 2026-08-24 через gh по трекерам конкурентов. Ниже — выжимка «что у них болит и что берём».
Карта конкурентов
| Проект | Что это | Похож на Rampart тем, что | Что взять |
|---|---|---|---|
| eBPFsentinel | Rust, один бинарник: firewall+IDS+DDoS через XDP/TC/uprobe | Ближайший аналог, та же архитектура | Rootless BPF token (kernel 6.9+); tail-call цепочки; MITRE-теги алертов; Swagger UI |
| CrabShield | Rust + XDP, гибрид L7→L3 | «Умный юзерспейс, кара в ядре» | Static musl бинарник; reaper истекающих банов; (log-tailing НЕ брать — хрупко) |
| lnvps_fw | XDP+TC защита VDS | Прямо наша ниша | ⭐ SYN-proxy в XDP; port learning из TC egress; лестница PORT_FILTER→SYN_PROXY→SOURCE_BLOCK + spoof gate; netns+veth harness |
| Oubliette | Linerate scrubber | Решает нашу боль с PoW | ⭐ RST-challenge: SYN-ACK с неверным ACK → спуф молчит, живой клиент шлёт RST → whitelist. Совместимо с любым клиентом |
| Couic (CERT Франции) | XDP-фаервол + REST API | Наш manager API | Anti-lockout; теги+TTL записей; OpenAPI spec; синк инстансов; fail2ban-интеграция |
| gamemann/XDP-Firewall (~830★) | Классический C XDP-фаервол | Референс по XDP | Pinned maps для внешнего управления; их issues = карта граблей верификатора |
| gen0sec/synapse | NDR: eBPF + JA4-фингерпринты + ratatui TUI | TUI как наш план | JA4+/JA4T фингерпринтинг (бан по отпечатку); fallback-цепочка XDP→nftables→iptables |
Топ-10 выводов из их issues/PRs (приоритет)
- Диагностика окружения при старте — проверять ядро/BTF/driver NIC до загрузки, человекочитаемый вердикт. ≈80% issues XDP-Firewall — про attach на неподдерживаемом окружении (#70/#71/#9/#44). Печатать режим (native/generic) честно.
- Эскалационная лестница защиты (lnvps_fw): pass-all steady state → PORT_FILTER → SYN_PROXY (tail-call, keyed cookie, ротация секрета) → SOURCE_BLOCK только со spoof-gate.
- RST-challenge (Oubliette) вместо мёртвого текстового PoW — универсально совместимо.
- REST API + OpenAPI + pinned maps: динамические IP-списки без перекомпиляции — самый частый feature request (#79/#77/#78 у gamemann); web-панель так и не сделана автором = свободная ниша.
- Anti-lockout + per-port баны: слепой XDP_DROP по IP = self-lockout по SSH (crab-shield docs). Whitelist обязателен, но не единственная защита.
- LRU во всех data-path maps — иначе silent default-deny под атакой (netshield DD-003). Per-src-IP rate limit не работает против spoofed flood 50–100 Mpps (gamemann #45) — нужны per-port/per-subnet/flow агрегаты.
- netns+veth тестовый харнесс + eBPF test_run тесты в CI (подтверждено в 2 проектах, отсутствует у всех) — наше конкурентное преимущество в надёжности.
- IPv6-паритет с первого дня + VLAN/QinQ парсинг (issue #75 висит годами).
- Rootless BPF token как опция, fallback CAP_BPF для ядер 5.15+ — не повторять жёсткий floor 6.9+ (ebpfsentinel отсёк enterprise) и не требовать root (crab-shield).
- События атак наружу с первого дня: poll-and-persist, дедуп алертов на переходе состояния (урок LNVPS #331 — отложили = дыра в продукте).
Наши козыри (чем превзошли уже)
- Двуязыная Knowledge Base (docs/kb/) — educational killer-feature, нет ни у одного конкурента
- Один Rust-бинарник без C-зависимостей сборки (класс сегфолтов/libbpf-hell gamemann исключён)
- Честные бенчмарки: цифры только с отчётами, методология опубликована
- Модульный лимит ≤300 строк + no-dead-code политика в CI
4. Anti-Regression — правила приёмки
- No dead code: каждый
pubимеет вызова вне#[cfg(test)]. - Config field = потребитель: нет поля без использования.
- Метрика регистрируется → обновляется: единственный writer на каждую метрику.
- Feature flag = сборка в CI:
--all-featuresзелёный, иначе фичи нет. - По умолчанию безопасно: нет дефолтных секретов; отсутствие обязательного env = fail-fast.
- Интеграционный тест на слой: config parse, filter logic, registry fail-fast (есть); новый слой = новый тест.
- Файл ≤ 250 строк, папка ≤ 4 .rs: CI-гейт
scripts/check_module_size.sh(ratchet-базлайн.module_size_baseline: легаси — WARN, новые нарушения — FAIL). - CI guardrails:
cargo clippy --all-targets -- -D warnings,cargo test, clang-build xdp/core/universal_filter.c, grep наchangeme. - README/TODO не врут: каждое число имеет ссылку на тест или отчёт.
5. Definition of Done
☐ cargo check / cargo test проходят
☐ cargo clippy --all-targets -- -D warnings — 0 warnings
☐ cargo fmt --check проходит
☐ Ни один файл не превышает 250 строк; ни в одной папке src/ больше 4 .rs-файлов
☐ Unit тесты покрывают happy path + 2+ error cases
☐ Нет мёртвого кода: pub без вызовов, конфиг-поле без потребителя, метрика без writer
☐ Нет дефолтных секретов
☐ README соответствует коду
☐ Документация обновлена
☐ CI зелёный
6. Anti-Patterns
❌ Тесты после кода. Пиши вместе.
❌ Файл > 250 строк или > 4 .rs в папке — сигнал декомпозировать/сгруппировать немедленно.
❌ TODO в коде без issue.
❌ Мёртвый код: pub без вызовов, конфиг-поле без потребителя, метрика без writer.
❌ «Бумажный слой»: фича описана, но не вызывается.
❌ Дефолтный секрет.
❌ Парсер за «один read» — TCP-поток приходит фрагментами.
❌ Feature flag, который не собирается в CI.
Версия: 5.0 | Обновлён: 2026-09-15 (bug-fix раунд: XDP unsafe, Redis reconnect/SCAN, CI-гейты, лимиты 250/4)