5.7 KiB
5.7 KiB
Net Alerter Daemon Deployment
Overview
The new net_alerter.py is a persistent systemd daemon that monitors device presence via passive network observation. It replaces the previous 5-minute cron-based implementation with three concurrent threads running indefinitely.
Architecture
Three Concurrent Threads
-
DHCP Sniffer (AF_PACKET raw socket)
- Captures DHCP packets passively on the network interface
- Extracts MAC, IP, and hostname from DHCP Discover/Request/Release messages
- Triggers
on_arrival()for Discover/Request,on_departure()for Release
-
RTM_NEWNEIGH Watcher (Netlink socket)
- Kernel pushes RTM_NEWNEIGH events when ARP neighbors reach REACHABLE/STALE/DELAY/PROBE states
- Supplements DHCP sniffer for devices that don't use DHCP
- Triggers
on_arrival()immediately
-
RTM_DELNEIGH Watcher (Netlink socket)
- Kernel pushes RTM_DELNEIGH events when ARP neighbors are deleted (5-10 minutes after last seen)
- Triggers
on_departure()when neighbor is removed from kernel table
Key Features
- Zero Active Probing — no nmap, no arp-scan, no ping. Only passively listens.
- Stdlib Only — no external dependencies (socket, struct, threading, time, logging, os)
- Thread-Safe —
known_devicesdict protected bythreading.Lock - Persistent Daemon — systemd service with auto-restart
- Logging to File + Stdout —
/opt/net_alerter/net_alerter.log - Matrix Alerting — sends alerts to configured Matrix room on arrival/departure
Prerequisites
Device Requirements
- Debian-based OS (Debian, Raspbian, Orange Pi OS)
- Python 3.6+
- Root access (AF_PACKET and Netlink require CAP_NET_RAW)
- Primary network interface (auto-detected from /proc/net/route)
Configuration Files
The daemon reads /opt/net_alerter/.env at startup:
MATRIX_HOMESERVER=https://m.example.org
MATRIX_ACCESS_TOKEN=<token from Matrix login>
MATRIX_ROOM_ID=!REDACTED:example.org
If .env doesn't exist, it will log a warning and try environment variables instead.
Deployment
Quick Deployment Script
cd ~/tools/bigbrother/net_alerter
./deploy-daemon.sh [user@host] [remote-dir]
# Examples:
./deploy-daemon.sh root@10.0.0.0
./deploy-daemon.sh root@10.0.0.0 /opt/net_alerter
Manual Deployment
- Copy files to device:
scp net_alerter.py root@10.0.0.0:/opt/net_alerter/
scp net_alerter.service root@10.0.0.0:/etc/systemd/system/
- Configure .env on device:
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
- Remove old cron:
ssh root@10.0.0.0 "crontab -l 2>/dev/null | grep -v net_alerter | crontab -"
- Enable and start service:
ssh root@10.0.0.0 "
systemctl daemon-reload
systemctl enable net_alerter
systemctl restart net_alerter
"
Verification
Service Status
ssh root@10.0.0.0 "systemctl status net_alerter --no-pager"
Expected output:
● net_alerter.service - Net Alerter
Loaded: loaded (/etc/systemd/system/net_alerter.service; enabled; preset: enabled)
Active: active (running)
View Logs
ssh root@10.0.0.0 "journalctl -u net_alerter -n 50 --no-pager"
Expected startup logs:
Net alerter starting on interface eth0
Seeded 12 devices from ARP cache
Net alerter running — DHCP sniffer + Netlink neighbor watcher active
Real-time Monitoring
ssh root@10.0.0.0 "journalctl -u net_alerter -f"
Then connect a test device to the network — you should see arrival alerts.
Event Examples
Device Arrival (DHCP-based)
[NET] ARRIVED: mobile.local (10.0.0.0) [Apple Inc.] MAC:a4:5e:60:00:11:22
Device Departure (ARP timeout)
[NET] DEPARTED: mobile.local (10.0.0.0) [Apple Inc.] MAC:a4:5e:60:00:11:22 — present 2h 34m
Configuration Environment Variables
Can override via env or .env file:
| Variable | Default | Purpose |
|---|---|---|
NET_ALERTER_ENV |
/opt/net_alerter/.env |
Path to config file |
MATRIX_HOMESERVER |
https://m.example.org |
Matrix server URL |
MATRIX_ACCESS_TOKEN |
(required) | Auth token for bot account |
MATRIX_ROOM_ID |
(required) | Room ID to send alerts to |
Troubleshooting
Service won't start
ssh root@10.0.0.0 "journalctl -u net_alerter -n 30"
Check for permission errors or missing dependencies.
No alerts being sent
- Verify
MATRIX_ACCESS_TOKENis valid:curl https://m.example.org/_matrix/client/v3/account/whoami -H "Authorization: Bearer <token>" - Verify bot is in the room: check room membership on Matrix client
- Check logs for HTTP errors:
journalctl -u net_alerter -e
Not detecting devices
- Ensure DHCP traffic is visible on the interface (some switches may filter it)
- For static IP devices, Netlink RTM_NEWNEIGH should still detect them
- Check ARP cache:
ip neigh show
High CPU usage
- Unlikely — threads sleep on socket reads. Check for malformed packets in logs.
- Reduce logging level if debug spam is heavy.
Uninstall
ssh root@10.0.0.0 "
systemctl stop net_alerter
systemctl disable net_alerter
rm /etc/systemd/system/net_alerter.service
systemctl daemon-reload
rm -rf /opt/net_alerter
"
Migration from Cron
The old cron-based implementation:
- Ran
net_alerter.pyevery 5 minutes - Had a cold start on each run
- Could miss transient devices in the 5-minute window
- Was CPU-hungry during scans (nmap probes)
The new daemon:
- Runs continuously, detecting changes in real-time
- Zero active probing
- Uses Kernel Netlink notifications for instant feedback
- Lower overall CPU + network overhead