Files
bigbrother/net_alerter/DAEMON_DEPLOYMENT.md
T

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

  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-Safeknown_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:

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

  1. 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/
  1. 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
  1. Remove old cron:
ssh root@10.0.0.0 "crontab -l 2>/dev/null | grep -v net_alerter | crontab -"
  1. 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_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

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