# 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 |

## Quick Start

```bash
cd net_alerter/
./deploy-daemon.sh root@<target-host>
```

Then configure Matrix credentials:
```bash
ssh root@<target-host> "cat > /opt/net_alerter/.env <<EOF
MATRIX_HOMESERVER=https://your-matrix-homeserver.example.com
MATRIX_ACCESS_TOKEN=<your_token>
MATRIX_ROOM_ID=!your-room-id:your-homeserver.example.com
EOF
chmod 600 /opt/net_alerter/.env
systemctl restart net_alerter"
```

Verify:
```bash
ssh root@<target-host> "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`:
```bash
MATRIX_HOMESERVER=https://your-matrix-homeserver.example.com
MATRIX_ACCESS_TOKEN=syt_...
MATRIX_ROOM_ID=!your-room-id:your-homeserver.example.com
```

### Optional Environment Variables
- `NET_ALERTER_ENV` — Path to config file (default: `/opt/net_alerter/.env`)

## Deployment Methods

### Method 1: Automated Script (Recommended)
```bash
./deploy-daemon.sh root@<target-host>
```

### Method 2: Manual
See `docs/deployment.md` for step-by-step guide with troubleshooting.

## Monitoring

### Service Status
```bash
ssh root@<target-host> "systemctl status net_alerter"
```

### Real-Time Logs
```bash
ssh root@<target-host> "journalctl -u net_alerter -f"
```

### Check Device Count
```bash
ssh root@<target-host> "journalctl -u net_alerter | grep 'Tracking.*devices'"
```

## Example Alerts

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

### Departure
```
[NET] DEPARTED: iphone.local (192.168.1.15) [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 `docs/deployment.md` for:
- Service won't start
- No alerts being sent
- Not detecting devices
- High CPU usage

## Migration from Cron

The legacy cron-based implementation 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
```bash
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
- Netlink: https://man7.org/linux/man-pages/man7/netlink.7.html
- RTnetlink: https://man7.org/linux/man-pages/man7/rtnetlink.7.html
- AF_PACKET: https://man7.org/linux/man-pages/man7/packet.7.html
- DHCP (RFC 2131): https://tools.ietf.org/html/rfc2131

## License
Part of BigBrother project.
