Add net_alerter daemon deployment documentation
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user