Commit Graph

126 Commits

Author SHA1 Message Date
Cobra 7a453ede6a Add BLE alerter configuration to operator_setup.sh (mode, devices, timeout, Matrix creds) 2026-04-10 06:32:29 -04:00
Cobra c778d27bac Update deploy-daemon.sh to deploy both net_alerter and ble_alerter 2026-04-10 06:31:55 -04:00
Cobra 6fac58aead Add unit tests for BLE alerter (mocked bleak, async scenarios) 2026-04-10 06:31:41 -04:00
Cobra 77dbf1baa3 Add systemd unit for BLE alerter (after bluetooth.target) 2026-04-10 06:31:39 -04:00
Cobra 358e07f7f6 Add BLE alerter daemon (passive scan, named-device tracking, Matrix alerts) 2026-04-10 06:31:38 -04:00
Cobra 6447a462c2 Fix ARRIVED spam — mark departing instead of popping from known_devices
When on_departure popped the device from known_devices, rapid RTM_NEWNEIGH
events during ARP cache rebuild each triggered on_arrival as if the device
was brand new, flooding the Matrix room with 5-10+ duplicate ARRIVED alerts.

Fix: keep device in known_devices with departing=True flag. on_arrival
silently cancels pending departure timers and returns without alerting when
it sees this flag. Timer callback checks flag before sending the alert and
only pops the device when departure is confirmed after 15 minutes.
2026-04-09 14:34:46 -04:00
Cobra 67cf907f74 Fix on_arrival() to always cancel departure timer on device re-arrival
- Bug: device departs → timer starts, but last_departed_time not set yet
  If device re-arrives before timer fires, timer never cancelled
  Result: false DEPARTED alert sent after re-arrival debounce expires

- Fix: Cancel any pending departure timer immediately on re-arrival,
  before checking last_departed_time

- Test: Added regression test that verifies timer is cancelled when
  device re-arrives before 15-min debounce expires, preventing false alerts

- All 10 tests passing
2026-04-09 13:28:34 -04:00
Cobra 504be80325 Deploy OUI database as part of net_alerter daemon installation
- scp oui.db to /opt/net_alerter/oui.db after daemon script
- Verify DB on remote via Python/sqlite3
- Confirm row count on target host
2026-04-09 13:05:34 -04:00
Cobra ab0688e1b3 Add SQLite OUI database lookup to net_alerter
- lookup_oui() now tries SQLite first (/opt/net_alerter/oui.db)
- Falls back to inline OUI_DICT if DB missing or query fails
- No network calls, local SQLite reads only
- Debug-level logging for failures (no output noise)
2026-04-09 13:05:18 -04:00
Cobra caf44576b6 Add false positive suppression to net_alerter — fix for #467
- Infrastructure IPs (gateway, self, broadcast) silently ignored in
  on_arrival() and on_departure(); seeded at startup from 'ip route'
- 15-minute departure debounce: alert only fires if device is still
  absent after 900s, eliminating ARP cache flush false positives
- 5-minute re-arrival suppression: ARRIVED alert skipped when device
  returns within 5 min of a recorded departure (covers interface flap)
- DHCP renewal dedup: known device re-announcing within 30 min skips
  ARRIVED alert
- Tests added for all four suppression paths (9 total, all passing)
2026-04-09 09:44:37 -04:00
Cobra 25f5775b6f Append QA review findings to consolidated security report
Delta reviewer validation completed:
- 12-item checklist validated (10 PASS, 2 PASS WITH CORRECTIONS, 1 FAIL)
- All 101 agent findings verified as complete and accurate
- 3 corrective actions identified: APT-001 deconfliction, bidirectional cross-refs, dedup transparency
- Report ready for remediation planning with low-effort corrections
2026-04-09 08:31:26 -04:00
Cobra c50be60f51 Append 4 operator Q&A sections with detailed exploitation scenarios and OPSEC analysis 2026-04-09 08:25:52 -04:00
Cobra f7b3796725 Make net_alerter alerts readable — fix hostname dedup and inline OUI lookup
- Replace broken OUI file lookup with inline dict of 200+ common vendors (works on Armbian)
- Fix hostname/IP duplication when reverse DNS fails (show IP once, not twice)
- Add format_arrival() and format_departure() helpers for consistent alert formatting
- Update on_arrival/on_departure to use new formatting functions
- Add comprehensive tests for hostname dedup and OUI lookup
2026-04-08 22:40:35 -04:00
Cobra 2ada26cbfe Update module count assertions to reflect reverse_tunnel removal 2026-04-08 22:26:06 -04:00
Cobra 95714885cd Strip OPSEC tool identity fingerprints
Replace all sensor.* logger namespaces with __name__ (generic module
identifiers instead of discoverable 'sensor.*' prefixes).

Change hardcoded 'bb' API user to 'admin' in config and code defaults.

Change hardcoded relay_user 'bb' to 'operator' — prevents network
profiling from exposing tool identity via SSH config.

Fixes #457, #458, #459
2026-04-08 22:18:35 -04:00
Cobra 84fa2d7b56 Add net_alerter README with quick start guide 2026-04-08 21:56:28 -04:00
Cobra a194642941 Add Orange Pi Zero 3 specific deployment guide 2026-04-08 21:56:03 -04:00
Cobra eb6221d29c Add net_alerter daemon deployment documentation 2026-04-08 21:55:39 -04:00
Cobra 571033f8dc Add deployment script for net_alerter daemon 2026-04-08 21:55:18 -04:00
Cobra e74ef10d1b Rebuild net_alerter as persistent daemon — DHCP sniffer + Netlink RTM_NEWNEIGH/DELNEIGH; removes 5-min cron, zero active probing 2026-04-08 21:55:02 -04:00
Cobra 1f90f9ca25 Replace nmap ARP scan with passive /proc/net/arp read — no active probing (#449)
- Removed get_local_subnets() and scan_subnet() — no longer needed
- Added read_arp_cache() to read kernel ARP table from /proc/net/arp
- Added fallback to 'ip neigh show' if /proc/net/arp unavailable
- Added lookup_oui() to query system /usr/share/hwdata/oui.txt for vendor names
- Removed subprocess nmap call and re import (no longer needed)
- run() now directly reads ARP cache instead of scanning subnets
- Zero active network traffic — purely passive monitoring
- Removed sudo requirement
2026-04-08 21:01:12 -04:00
Cobra 44b497ef41 Add missing detect_interface_with_retry function to fix engine startup 2026-04-08 20:59:35 -04:00
Cobra 245731e73b Robust interface detection — retry fallback chain for headless boot (#206)
Fixes interface auto-detection failures on Pi Zero 2W where wlan0 doesn't exist
at boot. Implementation:

- Added detect_interface_with_retry() function with 3x retry fallback chain
- Config-supplied interface preferred, then /proc/net/route, then UP interface
- Exponential backoff: 5s, 10s, 20s delays between retries
- Filters excluded prefixes: lo, tailscale*, wg*, tun*, docker*, veth*, br-*
- Used in Engine.__init__(), PacketCapture.start(), MacManager.start()
- Full test coverage: 10 tests for detection, backoff, filtering

Addresses issue where network stack initializes after boot and interfaces
become available after 5-10 second delay.
2026-04-08 20:58:43 -04:00
Cobra 6f421511de Add test to verify Engine instantiates and injects CaptureBus into passive modules (#204) 2026-04-08 20:57:10 -04:00
Cobra 6a79516a28 Enrich net_alerter alerts with OUI vendor and reverse DNS hostname
Parse nmap vendor name from MAC Address line (filtering out 'Unknown').
Fall back to socket.gethostbyaddr for IPs nmap didn't resolve a hostname
for. Alert label is now: 'hostname (vendor)' | 'hostname' | 'vendor' |
'unknown', in that priority order.
2026-04-08 20:31:49 -04:00
Cobra d164958831 Fix Cloudflare bot detection blocking net_alerter Matrix sends
urllib's default Python-urllib user agent is flagged by Cloudflare Bot
Fight Mode (error 1010) when m.mealeyfamily.com homeserver sits behind
Cloudflare. Add a browser-like User-Agent to Matrix PUT/POST requests so
Cloudflare passes the traffic through.
2026-04-08 20:19:24 -04:00
Cobra 019a96b205 Fix flash bugs: remove netplan wifi conflict, suppress eth default route, force IPv4 for Tailscale install
- Remove 20-wifi.yaml netplan block (Bug 1): causes netplan to spawn its own wpa_supplicant instance, which claims ctrl_iface and blocks wpa_supplicant@wlan0.service. The per-interface systemd service is the correct approach.
- Add cleanup line to remove any pre-existing 20-wifi.yaml from the Armbian image.
- Patch 10-dhcp-all-interfaces.yaml to suppress default route on ethernet (Bug 2): without this, ethernet DHCP default route metric 100 beats WiFi metric 1024, routing internet traffic to ethernet which has no upstream. Causes Tailscale and firstboot to fail.
- Force IPv4 resolution in Tailscale curl (Bug 3): some homelab/ISP networks lack IPv6 internet routes. IPv6 DNS resolution for tailscale.com causes immediate curl failure on first boot.
2026-04-08 19:37:38 -04:00
Cobra 248ba78e15 Fix WiFi: enable wpa_supplicant@wlan0 — instance was never linked 2026-04-08 15:56:48 -04:00
Cobra 334f9830e1 Replace .bigbrother with .implant in all identity strings — avoid tool name exposure on fresh flash 2026-04-08 14:08:00 -04:00
Cobra e114d6067a Remove autossh reverse tunnel references — module deleted, causing ImportError on startup 2026-04-08 14:07:52 -04:00
Cobra 1dbcb6aad3 Wire net_alerter cron into setup.sh — reads bb-config.env, seeds baseline on first boot 2026-04-08 13:50:58 -04:00
Cobra b0fd5865cc Make binary downloads non-fatal and add force-confold for nftables conffile prompt 2026-04-08 12:22:25 -04:00
Cobra 3cdccbf47d Fix WiFi conflict and SSH accessibility on fresh flash
- Remove wpa_supplicant@wlan0.service enablement: Netplan spawns its own
  wpa_supplicant instance, enabling the @wlan0 unit creates a second one
  that fights for the socket, causing WiFi instability and SSH drops
- Write /etc/nftables.conf to card at flash time: Armbian bookworm default
  nftables policy drops all input; SSH was unreachable despite sshd running.
  Ruleset allows established, loopback, ICMP, and TCP/22 only

Fixes DevTrack #317 and #295
2026-04-08 11:08:02 -04:00
Cobra 90c26ae24d Fix firstboot service startup: GOPATH env, enable all services, add bettercap passive caplet
- Set HOME/GOPATH/GOMODCACHE before go install kerbrute on arm64 to fix
  'module cache not found' abort that prevented --enable-service from running
- Enable bigbrother-capture, bigbrother-watchdog, and bettercap.service
  in --enable-service block (previously only bigbrother-core was enabled)
- Add services/bettercap.service: runs passive_recon.cap with net.recon +
  net.sniff + events.stream instead of idle api.rest only
- bettercap.service depends on bigbrother-core to ensure engine is up first

Fixes DevTrack #311 and #312
2026-04-08 10:51:09 -04:00
Cobra d66b547045 Fix wpa_supplicant conflict and firstboot robustness
- Remove generic wpa_supplicant.service symlink when wpa_supplicant@wlan0 is enabled — both services fight over wlan0 causing WiFi instability and SSH drops
- Add udev rule to disable WiFi power saving (aw859a drops connections under load with power save on)
- Drop set -e from firstboot script so a failing step does not kill the whole run
- Guard setup.sh call — skip gracefully if not present (dev/test scenario)

Fixes #295 and #296
2026-04-07 21:50:51 -04:00
Cobra 1803c54182 Switch WiFi config from NetworkManager to Netplan+wpa_supplicant
Armbian minimal uses systemd-networkd+wpa_supplicant via Netplan, not NM.
Write Netplan YAML, wpa_supplicant-wlan0.conf, and networkd .network file.
Enable wpa_supplicant@wlan0.service via symlink if template exists.
2026-04-07 17:02:36 -04:00
Cobra d2f4f9759d Fix SD flash mounting wrong partition — Armbian p1=boot p2=rootfs
WiFi, SSH keys, root password, firstboot service were all being written to
the FAT32 boot partition (p1) instead of the ext4 rootfs (p2). Detect the
ext4 partition by filesystem type and mount that as MOUNT_POINT.
2026-04-07 16:44:22 -04:00
Cobra 61a1756dae Fix mktemp overwrite prompt in autossh tunnel keygen 2026-04-07 15:56:59 -04:00
Cobra 56ad5662ac Fix ssh-keygen overwrite prompt and key landing in root home
mktemp creates the file before ssh-keygen runs — keygen sees it exists
and prompts. Switch to mktemp -d so keygen writes a fresh file.

When run via sudo SUDO_USER is set but HOME=/root. Resolve the real
home via getent so the key lands in the operator's ~/.ssh, not root's.
2026-04-07 15:47:31 -04:00
Cobra 6cb48909b2 Save generated SSH key locally to ~/.ssh/bb-<device_id>
Infisical is the backup copy. Local key at a predictable path means
no hunting — ssh -i ~/.ssh/bb-<device_id> just works.
2026-04-07 15:22:55 -04:00
Cobra 42c05f37e6 Fix ANSI rendering and Infisical key storage in operator wizard
echo calls in summary/final sections were missing -e flag so ANSI
escape codes printed literally instead of rendering.

Infisical SSH key storage was targeting a non-existent 'bigbrother'
folder, silently failing to store the private key. Removed folder
argument so keys store at root where creds CLI can retrieve them.
2026-04-07 15:22:16 -04:00
Cobra e00769631a Remove homeserver default — no infrastructure fingerprints in wizard 2026-04-07 14:56:46 -04:00
Cobra 4c332eabb4 Proper Matrix alerter support with client API
Matrix doesn't use a simple webhook URL — needs homeserver, room ID,
and bot token separately. Uses PUT /_matrix/client/v3/rooms/.../send
with Bearer token auth. Room ID is bash-encoded (! → %21, : → %3A)
to avoid Python dependency pre-setup. Also adds ntfy and plain
webhook as options under a typed alerter menu.
2026-04-07 14:55:23 -04:00
Cobra 84f0775f76 Align device ID with MAC profile OUI for consistent network identity
Device ID is now a MAC-format hex string (12 chars) using the same
OUI as the randomly selected device profile. If the device gets an
Amazon OUI for its MAC, the device ID starts with fc65de. Hostname,
MAC, and device ID all point to the same vendor — no inconsistency
for anyone watching the network.
2026-04-07 14:48:22 -04:00
Cobra d8de49a53d Remove bb- prefix from device ID default
bb- prefix is a tool fingerprint — visible in Infisical key names,
alerter payloads, and config files on the device. Default is now
a plain 10-char hex string with no identifying prefix.
2026-04-07 14:44:59 -04:00
Cobra af124cc6d0 Default VPN to Tailscale, add auth key expiry warning
Tailscale handles NAT traversal automatically via DERP relay — more
reliable than WireGuard for devices landing on unknown networks.
Add reminder to use reusable non-expiring keys for long-term drops.
2026-04-07 14:41:17 -04:00
Cobra b0fb5af1fb Include device IP and hostname in firstboot alerter beacon
Blind drops need some way to locate the device when no VPN is selected.
Alerter now reports public IP (via ipify) with fallback to local IP,
plus hostname — gives enough info to SSH directly on same-network drops.
2026-04-07 14:37:04 -04:00
Cobra 2b00b28de6 Add reverse SSH tunnel (autossh) as VPN option in operator wizard
Generates a dedicated tunnel keypair during setup, prints public key
for operator to pre-stage on server, writes private key to SD card.
On first boot: installs autossh, writes bb-tunnel.service with
correct RemoteForward and reconnect settings. Zero network traffic
until operator initiates connection through the tunnel port.
2026-04-07 14:30:10 -04:00
Cobra ae79d64913 Align default hostname with MAC device profiles for OPSEC consistency 2026-04-07 14:19:55 -04:00
Cobra 2b53da80d0 Fix wizard: defaults for all prompts, random hostname/device-id, download robustness
- Add prompt_default() helper: shows defaults, accepts Enter to use them
- WiFi: default=n (skip), keeps passphrase prompt loop
- Root password: auto-generate with openssl, show in summary if used, operator can override
- SSH key: default=1 (generate new)
- Device ID: auto-generate bb-<8-char-uuid>
- Boot mode: default=1 (passive)
- VPN: default=1 (none)
- Hostname: NEW section with auto-generated node-<6-char-uuid> default
- Alerter: default=n (disabled)
- Download: use curl -L (no -f), verify file exists and >50MB
- Config summary: show hostname, mask password (show auto-generated clearly)
- Apply config: write BB_HOSTNAME to /etc/hostname and /etc/hosts
- No eval with user input: use printf -v for variable assignment
2026-04-07 14:17:01 -04:00