Files
bigbrother/net_alerter
Cobra 65d42229ad Fix P1/P2 audit findings from #671 review
P1 Fixes:
- Signal count enrollment logic: Changed from broken signal_count increment to tracking distinct signal types (BLE vs WiFi) using a set. Device enrolls when len(signal_types) >= 2, ensuring multi-source correlation.
- DNS mDNS pointer endianness: Added bounds check to prevent out-of-bounds reads when following DNS compression pointers. Checks pointer_offset < offset and pointer_offset < len(payload) before recursing.
- Nested RLock fragility: Refactored enrollment callback to not acquire lock (caller _ingest_signal holds it). Renamed _on_device_enrolled() to _fire_enrollment_callback() and removed lock acquisition.

P2 Fixes:
- BLE Handoff parsing: Implemented full HCI packet parsing to extract Apple Company ID (0x004C), Handoff message type (0x0C), and sequence number (bytes 4-5, big-endian). Calls _ingest_signal() with handoff_seq parameter.
- DNS record count overflow: Capped total_records at 1000 to prevent unbounded loop DoS on crafted mDNS packets.
- device_store unbounded growth: Added simple eviction when store exceeds 500 entries - evicts 100 oldest by first_seen timestamp. No LRU needed for MVP.

All 40 existing tests continue to pass.
2026-04-14 12:46:44 -04:00
..

Net Alerter — Device Presence Tripwire Daemon

Persistent systemd daemon that passively monitors device presence on the network via DHCP sniffing and Netlink kernel events. Sends Matrix alerts on device arrival/departure.

Files

File Purpose
net_alerter.py Main daemon (stdlib-only, 15K)
net_alerter.service Systemd unit file
deploy-daemon.sh Universal deployment script
DAEMON_DEPLOYMENT.md General deployment guide
ORANGE_PI_DEPLOYMENT.md Orange Pi Zero 3 specific guide
deploy.sh Legacy cron-based deployer (deprecated)

Quick Start (Orange Pi Zero 3 @ 10.0.0.0)

cd ~/tools/bigbrother/net_alerter
./deploy-daemon.sh root@10.0.0.0

Then configure Matrix credentials:

ssh root@10.0.0.0 "cat > /opt/net_alerter/.env <<EOF
MATRIX_HOMESERVER=https://m.example.org
MATRIX_ACCESS_TOKEN=<your_token>
MATRIX_ROOM_ID=!REDACTED:example.org
EOF
chmod 600 /opt/net_alerter/.env
systemctl restart net_alerter"

Verify:

ssh root@10.0.0.0 "journalctl -u net_alerter -n 30"

How It Works

Three Concurrent Threads

  1. DHCP Sniffer — AF_PACKET raw socket captures DHCP traffic

    • Extracts MAC, IP, hostname from DHCP packets
    • Triggers arrival on Discover/Request, departure on Release
  2. Netlink RTM_NEWNEIGH Watcher — Kernel ARP neighbor creation events

    • Fires when device reaches REACHABLE state
    • Handles static-IP devices
  3. Netlink RTM_DELNEIGH Watcher — Kernel ARP neighbor deletion events

    • Fires when device times out from ARP cache (5-10 minutes)
    • Triggers departure alert

Zero Active Probing

  • No nmap, nping, arp-scan, ping
  • Only passive listening on raw sockets
  • No traffic generated by this daemon

Dependencies

  • Runtime: Python 3.6+, root access
  • Libraries: stdlib only (socket, struct, threading, time, logging, os)
  • Data: OUI database at /usr/share/hwdata/oui.txt or /usr/share/misc/oui.txt (usually present on Debian)

Configuration

.env file at /opt/net_alerter/.env:

MATRIX_HOMESERVER=https://m.example.org
MATRIX_ACCESS_TOKEN=syt_...
MATRIX_ROOM_ID=!REDACTED:example.org

Optional Environment Variables

  • NET_ALERTER_ENV — Path to config file (default: /opt/net_alerter/.env)

Deployment Methods

./deploy-daemon.sh root@10.0.0.0

Method 2: Manual

See DAEMON_DEPLOYMENT.md → Manual Deployment section

Method 3: Orange Pi Specific

See ORANGE_PI_DEPLOYMENT.md for step-by-step guide with troubleshooting

Monitoring

Service Status

ssh root@10.0.0.0 "systemctl status net_alerter"

Real-Time Logs

ssh root@10.0.0.0 "journalctl -u net_alerter -f"

Check Device Count

ssh root@10.0.0.0 "journalctl -u net_alerter | grep 'Tracking.*devices'"

Example Alerts

Arrival

[NET] ARRIVED: iphone.local (10.0.0.0) [Apple Inc.] MAC:a4:5e:60:ab:cd:ef

Departure

[NET] DEPARTED: iphone.local (10.0.0.0) [Apple Inc.] MAC:a4:5e:60:ab:cd:ef — present 2h 34m

Performance

Metric Value
CPU <1% (idle, thread sleeping on sockets)
Memory ~15-20 MB
Network Traffic 0 (passive only)
Detection Latency <100ms for Netlink events, 5-10min for ARP timeouts
Startup Time ~2 seconds

Troubleshooting

See DAEMON_DEPLOYMENT.md → Troubleshooting section for:

  • Service won't start
  • No alerts being sent
  • Not detecting devices
  • High CPU usage

Migration from Cron

The legacy cron-based implementation (deploy.sh) ran every 5 minutes with active probing (nmap). The new daemon:

  • Runs continuously
  • Zero active probing
  • Real-time detection via kernel Netlink notifications
  • Lower CPU and network overhead

To migrate, stop the old cron and deploy the daemon.

Development

Code Structure

  • load_env() — Parse .env configuration
  • seed_from_arp_cache() — Bootstrap known devices on startup
  • lookup_oui() — MAC vendor lookup
  • on_arrival()/on_departure() — Event handlers, trigger Matrix alerts
  • dhcp_sniffer() — DHCP packet capture thread
  • parse_dhcp() — Extract MAC/IP/hostname from DHCP payloads
  • netlink_watcher() — Netlink event listener thread
  • parse_netlink()/parse_ndmsg() — Kernel neighbor event parsing
  • send_alert() — POST to Matrix API

Testing

python3 -m py_compile net_alerter.py  # Syntax check
python3 -c "import net_alerter"        # Import check

Note: Full functional tests require root, raw sockets, and live DHCP traffic.

References

License

Part of BigBrother project.