Add net_alerter daemon deployment documentation

This commit is contained in:
Cobra
2026-04-08 21:55:39 -04:00
parent 52872794ee
commit a54acf32b8
+197
View File
@@ -0,0 +1,197 @@
# 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
1. **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
2. **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
3. **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_devices` dict protected by `threading.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:
```bash
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
```bash
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
1. **Copy files to device:**
```bash
scp net_alerter.py root@10.0.0.0:/opt/net_alerter/
scp net_alerter.service root@10.0.0.0:/etc/systemd/system/
```
2. **Configure .env on device:**
```bash
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
```
3. **Remove old cron:**
```bash
ssh root@10.0.0.0 "crontab -l 2>/dev/null | grep -v net_alerter | crontab -"
```
4. **Enable and start service:**
```bash
ssh root@10.0.0.0 "
systemctl daemon-reload
systemctl enable net_alerter
systemctl restart net_alerter
"
```
## Verification
### Service Status
```bash
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
```bash
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
```bash
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
```bash
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_TOKEN` is 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
```bash
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.py` every 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