firmware&dashboard changes

This commit is contained in:
bot
2026-04-05 13:06:25 +03:00
parent 2636ea1e11
commit e01bbd9e56
11 changed files with 419 additions and 84 deletions
+65 -28
View File
@@ -28,12 +28,12 @@ This is a learning/research project covering distributed systems, event-driven a
### Active nodes
| node_id | MAC | Location / Port |
|----------|-------------------|------------------------|
| F68D6E30 | 44:1b:f6:8d:6e:30 | desk /dev/ttyACM0 |
| A1D658D4 | e0:72:a1:d6:58:d4 | desk /dev/ttyACM1 |
| A1D700C4 | e0:72:a1:d7:00:c4 | desk /dev/ttyACM2 |
| A1D6F190 | e0:72:a1:d6:f1:90 | deployed (another room)|
| node_id | MAC | Location |
|----------|-------------------|-------------------------|
| F68D6E30 | 44:1b:f6:8d:6e:30 | room 1 (permanent) |
| A1D658D4 | e0:72:a1:d6:58:d4 | room 2 (permanent) |
| A1D700C4 | e0:72:a1:d7:00:c4 | dev machine /dev/ttyACM2|
| A1D6F190 | e0:72:a1:d6:f1:90 | dev machine /dev/ttyACM1|
---
@@ -124,10 +124,15 @@ esp32_cluster/
Each node:
- Connects to WiFi `sandbox`
- Scans for nearby APs every 15 seconds (active scan, includes hidden SSIDs)
- Hops across all 13 2.4 GHz channels (300ms dwell per channel) while sniffing
- Captures probe request frames passively (promiscuous mode) between scans
- Sends a heartbeat packet every 10 seconds (uptime, free heap, WiFi RSSI to router)
- Sends beacon, probe, and heartbeat events as UDP JSON packets to the coordinator
- Captures deauth and disassoc frames (0xC0 / 0xA0)
- Captures association and reassociation request frames (0x00 / 0x20) with SSID IE parsing
- Sends a heartbeat packet every 10 seconds (uptime, free heap, WiFi RSSI to router, queue drop counters)
- Sends all events as UDP JSON packets to the coordinator
- `node_id` is derived from bytes 25 of the ESP32's base MAC address
- Events are buffered in FreeRTOS queues and flushed once per scan cycle when back on the home channel
- If a deauth with reason code 2 is seen at RSSI ≥ -60 dBm, an alert flag triggers an immediate flush on the home channel without waiting for the next scan
### Event formats
@@ -179,17 +184,37 @@ Each node:
- `reason` is the 802.11 reason code (7 = class 3 frame received from non-associated station, common in attack tools)
- Captured passively in the same promiscuous callback as probe requests, flushed to coordinator after each scan cycle
**Assoc / Reassoc event** (client joining a network):
```json
{
"node_id": "F68D6E30",
"ts": 12345,
"type": "assoc",
"src": "AA:BB:CC:DD:EE:FF",
"bssid": "11:22:33:44:55:66",
"ssid": "NetworkName",
"rssi": -55
}
```
- `type` is `assoc` (0x00) or `reassoc` (0x20)
- SSID is parsed from the first Information Element in the frame body (IE tag 0x00)
- Captures real client→AP join events, not just passive probe searches
**Heartbeat event** (node health, sent every 10 seconds):
```json
{
"node_id": "F68D6E30",
"ts": 12345,
"type": "heartbeat",
"uptime_ms": 123456,
"free_heap": 245000,
"wifi_rssi": -62
"node_id": "F68D6E30",
"ts": 12345,
"type": "heartbeat",
"uptime_ms": 123456,
"free_heap": 245000,
"wifi_rssi": -62,
"probe_drops": 0,
"deauth_drops": 0,
"assoc_drops": 0
}
```
- `probe_drops`, `deauth_drops`, `assoc_drops` count events lost due to queue overflow since boot. Non-zero values indicate the node is seeing more traffic than the queue sizes can absorb.
- `imp`: `high` if RSSI >= -50, `low` if <= -80, else `normal`
- `ssid` in probe events is the network the device is searching for — empty means wildcard (any network)
@@ -216,16 +241,21 @@ The same binary works on every node — `node_id` is auto-derived from the MAC,
### config.h reference
| Constant | Default | Purpose |
|--------------------|------------------|-------------------------------------------|
| `WIFI_SSID` | `sandbox` | WiFi network to connect to |
| `COORDINATOR_IP` | `192.168.1.133` | Orange Pi address |
| `COORDINATOR_PORT` | `5005` | UDP port |
| `SCAN_INTERVAL_MS` | `15000` | How often to run a beacon scan (ms) |
| `PROBE_SNIFF` | `1` | Enable/disable probe sniffing (1/0) |
| `PROBE_DEDUP_SECS` | `30` | Suppress duplicate probe MAC+SSID (secs) |
| `PROBE_QUEUE_SIZE` | `32` | Max probe events buffered between scans |
| `DEAUTH_QUEUE_SIZE`| `32` | Max deauth/disassoc events buffered |
| Constant | Default | Purpose |
|-------------------------|-----------|----------------------------------------------------------------|
| `WIFI_SSID` | `sandbox` | WiFi network to connect to |
| `COORDINATOR_IP` | `192.168.1.133` | Orange Pi address |
| `COORDINATOR_PORT` | `5005` | UDP port |
| `SCAN_INTERVAL_MS` | `15000` | How often to run a beacon scan (ms) |
| `HEARTBEAT_INTERVAL_MS` | `10000` | How often to send a heartbeat (ms) |
| `PROBE_SNIFF` | `1` | Enable/disable probe/deauth/assoc sniffing (1/0) |
| `PROBE_DEDUP_SECS` | `30` | Suppress duplicate probe MAC+SSID (secs) |
| `DEDUP_CACHE_SIZE` | `64` | Number of MAC+SSID pairs tracked for dedup |
| `PROBE_QUEUE_SIZE` | `128` | Max probe events buffered between flushes |
| `DEAUTH_QUEUE_SIZE` | `128` | Max deauth/disassoc events buffered |
| `ASSOC_QUEUE_SIZE` | `32` | Max assoc/reassoc events buffered |
| `HOP_DWELL_MS` | `300` | Ms to dwell on each channel while hopping (13ch × 300ms ≈ 4s) |
| `RSSI_ALERT_THRESHOLD` | `-60` | RSSI floor for immediate-flush deauth alert (dBm) |
---
@@ -327,21 +357,28 @@ The `oui.txt` file is the IEEE public OUI database (39,171 entries as of downloa
- [x] Node firmware: beacon scan + probe sniffing
- [x] Four ESP32-S3 nodes flashed and running
- [x] UDP ingestor (`udp_ingest.py`) — beacon + probe routing with field validation
- [x] Web dashboard: Feed, Networks, Cross-node, Clients, Node detail views
- [x] OUI vendor lookup in Clients view
- [x] Web dashboard: Feed, Networks, Cross-node, Clients, Alerts, Search, Presence, Node detail
- [x] OUI vendor lookup in Clients view (vendor grouping + randomized MAC detection)
- [x] Dashboard split into HTML / CSS / JS (no monolithic file)
- [x] Deployed to Orange Pi as systemd services (runs 24/7)
- [x] All four nodes sending to Orange Pi, confirmed live
- [x] Node heartbeat every 10s — uptime, free heap, AP signal, drives online/offline status
- [x] RSSI history chart per network (canvas, per-node coloured lines, 1h/2h/6h/24h range)
- [x] Presence tab — Present Now, New Arrivals, Regulars
- [x] Presence tab — Present Now, New Arrivals, Regulars (fixed key mismatch bug)
- [x] Deauth/disassoc frame detection — burst detection with multi-node confirmation, Alerts tab
- [x] Alerts tab — most impersonated networks, most targeted devices, burst detection, raw feed
- [x] Search tab — cross-table lookup by MAC, SSID, BSSID, or vendor name
- [x] Node detail view — 2×5 stat cards with animated border, fixed alphabetical sidebar order
- [x] Channel hopping — 13 channels at 300ms dwell, flush on homeChannel pass
- [x] Assoc/reassoc frame capture — client join events with SSID IE parsing
- [x] RSSI-triggered alert flush — immediate homeChannel flush on close-range deauth attack signature
- [x] Queue drop counters — tracked per queue in firmware, reported in heartbeat, stored in DB
- [x] SQLite indexes — received_at, node_id, bssid, src_mac, src, dst across all event tables
- [x] Dashboard query caps — 300-row limits on Clients, Networks, Cross-node to keep UI responsive
- [ ] Attack session reconstruction — group deauth events into discrete sessions by source/time
- [ ] Scan interval control from dashboard
- [ ] Surface assoc events in dashboard (Sessions tab or Search results)
- [ ] DB pruning / retention policy (events.db grows indefinitely)
- [ ] Scan interval control from dashboard
---