Repository navigation
Architecture
aiXis Studio edited this page Oct 4, 2026
·
1 revision
Full version with maintainer notes / version complète : docs/architecture.md
┌──────────────────────────────────────────────────────────────┐
│ Browser / Electron renderer (React + D3) │
│ WS ◄──── batch (250 ms) ──── REST (token: X-Snitch-Token) │
└───────────────────────────▲──────────────────────────────────┘
│ 127.0.0.1 only
┌───────────────────────────┴──────────────────────────────────┐
│ FastAPI (api/main.py) │
│ _pkt_queue (bounded) → _drain_loop → _process_batch │
│ filters → LAN accounting → graph aggregates → detector │
├──────────────────────────────────────────────────────────────┤
│ capture/sniffer.py — PacketSniffer thread │
│ capture/pcap.py — ctypes → wpcap.dll / libpcap.so │
│ capture/parser.py — own parser: Ethernet, IPv4/IPv6, │
│ TCP/UDP, DNS answers, TLS SNI │
│ ConnectionTable — psutil snapshot every ~1.5 s │
│ (proto, local_port) → (pid, name) │
├──────────────────────────────────────────────────────────────┤
│ scanner/arp_scanner.py — system ARP table (passive) │
│ detection/anomaly.py — NEW_HOST, PORT_SCAN, BEACON, │
│ VOLUME_SPIKE, MEDIA_EXFIL, LAN │
│ resolver/dns_geo.py — observed DNS/SNI > reverse DNS │
│ > offline .mmdb (DB-IP/GeoLite2) │
│ storage/db.py — SQLite: traffic, alerts, settings │
└──────────────────────────────────────────────────────────────┘
-
No per-packet coroutines — one bounded queue, one drain task, one
batchWebSocket message per ~250 ms tick. -
Direction-aware ports — classification always uses
remote_port;dst_porton inbound traffic is a local port and is never used for classification. - Zero third-party network calls in the codebase — even geolocation is offline.
- Bounded state — every container in the detector is size-bounded behind a lock.
-
Enrichment — observed DNS/SNI map → reverse DNS → offline
.mmdb; fire-and-forget, deduplicated per IP.
| Layer | Technology |
|---|---|
| Packet capture | ctypes → libpcap/Npcap, own parser (IPv4/IPv6/TCP/UDP/DNS/TLS-SNI) |
| Backend API | FastAPI · WebSockets · SQLite |
| Frontend | React 18 · Vite · D3.js v7 · TopoJSON |
| Desktop | Electron 44 |
| Geolocation | DB-IP Lite (CC BY 4.0, bundled) · MaxMind .mmdb supported |
A ConnectionTable snapshots OS connections via psutil every ~1.5 s and maps (protocol, local_port) → (pid, name). The top 5 processes are reported per connection — attribution is best-effort by design (kernel-level attribution would require a driver).
Le schéma ci-dessus s'applique tel quel. Points clés :
-
Capture :
pcap.py(ctypes vers libpcap/Npcap) +parser.pymaison (Ethernet, IPv4/IPv6, TCP/UDP, DNS, SNI TLS). -
Pipeline : file bornée → tâche de vidage unique (~4 Hz) → un message WS
batchpar tick. Aucune coroutine ni diffusion par paquet. -
Classification : toujours sur
remote_port, direction-aware. -
Enrichissement : DNS/SNI observés → DNS inverse →
.mmdblocal ; tâches dédupliquées. -
Données : SQLite local — trafic, alertes, réglages, suppressions, historiques (
host_history,process_history).
ConnectionTable prend un instantané psutil toutes les ~1,5 s et associe (protocole, port_local) → (pid, nom). Top 5 par connexion — attribution best-effort (une attribution au niveau noyau exigerait un pilote).
| Module | Rôle |
|---|---|
capture/ |
pcap, parser, sniffer, media_monitor |
api/ |
FastAPI, sécurité (jeton, allowlist origines) |
detection/ |
Moteur d'anomalies |
classifier/ |
Listes de trackers/CDN (fichiers éditables) |
resolver/ |
DNS inverse + géolocalisation hors ligne |
scanner/ |
Découverte LAN passive (table ARP) |
storage/ |
SQLite : trafic, alertes, réglages, historiques |
Snitch Wiki
Getting started / Démarrage
Docs (EN + FR)
Help / Aide (EN + FR)
Project / Projet