============================================================ Mantis TODO (updated 2026-05-21) ============================================================ -- DONE (archived) ---------------------------------------- [x] CSV rolling log with date-based filenames [x] Migrate inference engine to ort-tract (pure Rust) [x] Improve ML inference throughput under high load [x] ML + Rule fusion decision layer (FusionEngine) [x] Code audit: remove .unwrap() / eprintln() outside build.rs [x] Frontend detection page [x] GeoIP unbounded thread explosion (semaphore cap = 8) [x] maxminddb DEBUG log flood (EnvFilter "maxminddb=warn") [x] Frontend UnifiedAlert API alignment (detection.tsx, WebSocketProvider, config.ts, dashboard.tsx) [x] Rule engine -> replaced entirely by Suricata daemon mode Removed: vectorscan, rusqlite, protolens, pcre2, byte_test/jump/extract, app-layer-protocol, threshold, QUIC parser, suppress list (SQLite). Replaced by: suricata daemon + veth mirror + EVE JSON unix socket. Suricata handles all signature matching; Mantis reads alerts via output.rs. [x] Suricata EVE socket race condition (bind before spawn) [x] af-packet block-size too small (32768 -> 131072) [x] Suricata noisy rule categories (exclude emerging-info/policy/user_agents) [x] suppress.conf: add known-benign SIDs (2013504 APT User-Agent etc.) -- SHOULD DO (detection capability) ---------------------- [ ] TLS / JA3 fingerprint analysis Goal: detect encrypted malware C2 / beaconing without decryption. Step 1: add tls event type to suricata.yaml EVE outputs (extended: yes). Step 2: parse event_type == "tls" in output.rs -> extract ja3.hash, sni, cert info. Step 3: build JA3 whitelist (HashSet) from observed normal traffic baseline. Step 4: alert on unknown JA3 hash + check cert anomalies (self-signed, expired, CN mismatch). Step 5: beacon detection -- low stddev of inter-connection interval to same dst_ip on 443. No model needed for steps 1-5; add dedicated classifier only if false-positive rate is unacceptable after baseline calibration. Files: detection/suricata/output.rs, detection/suricata/tls.rs (new), model/log/suricata.rs, model/error/suricata.rs [ ] XDP active response (auto-block) Goal: block confirmed attacker IPs at kernel level (< 1 us per packet). Design: BPF_MAP_TYPE_LRU_HASH keyed by src IPv4/IPv6; XDP program checks map and returns XDP_DROP before any userspace processing. Trigger: FusionEngine fires a fusion or high-confidence ML alert -> insert src_ip into block map via userspace BPF map update API. Expiry: separate tokio task sweeps entries older than block_ttl_secs (config). API: POST /api/blacklist still works for manual entries; auto-block is additive. Files: ingress-ebpf/src/main.rs (map lookup + XDP_DROP), core/ebpf/xsk_manager.rs (map fd plumbing), detection/fusion.rs (trigger auto-block on high-confidence events) -- SHOULD DO (runtime management) ------------------------ [ ] Account system + persistent lists Two SQLite files: static/db/app.db accounts (id, username, password_hash, role, created_at) sessions (token TEXT PK, account_id, expires_at) whitelist (id, ip_net TEXT, comment TEXT, created_at) blacklist (id, ip_net TEXT, action TEXT, comment TEXT, created_at) Migration: CREATE TABLE IF NOT EXISTS at startup in AppServices::init(). File: core/infrastructure/app_db.rs (new) [ ] HTTP API -- auth / accounts / lists / system All routes require Bearer token except POST /api/auth/login. Auth: POST /api/auth/login, POST /api/auth/logout, GET /api/auth/me Accounts: GET/POST /api/accounts, PUT /api/accounts/:id/password, DELETE /api/accounts/:id Suppress: GET/POST/DELETE /api/suppress (writes suppress.conf + signals Suricata reload) Lists: GET/POST/DELETE /api/whitelist, /api/blacklist System: POST /api/system/restart Files: web/routes/{auth,accounts,lists,system}.rs, web/middleware/auth.rs [ ] Graceful restart Trigger: POST /api/system/restart or SIGTERM. Steps: drain flow tracker (2 s), XDP unload, flush CSV, tokio shutdown, re-exec. Files: core/ebpf/ (detach helpers), main.rs (signal handler + re-exec) -- OPEN QUESTIONS ----------------------------------------- [ ] Dashboard attack/protocol counters never reset Accumulate for entire session lifetime; charts show historical totals. Consider: sliding window reset every N minutes, or cap at last 500 alerts. File: mantis-frontend/...dashboard.tsx