f6047a0b6e197059f143bc49b85328cf5197367a
mac_watcher
Polls a switch MAC address table via SNMP. Sends email alerts for unknown MACs. Exposes a Prometheus metrics endpoint reflecting the current switch state.
Requirements
- Debian Linux
- Python 3.11+
snmpwalk(apt install snmp)- Python dependencies:
pip install -r requirements.txt --break-system-packages
Install
apt install snmp
cd /opt
git clone https://git.mosad.xyz/localhorst/mac_watcher.git
cd /opt/mac_watcher
pip install -r requirements.txt --break-system-packages
Edit config.py and set all values.
chmod +x /opt/mac_watcher/mac_watcher.py
cp scripts/mac-watcher.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now mac-watcher.service
Configuration
All settings are in config.py.
| Setting | Description |
|---|---|
switch_ip_addr |
IP of the managed switch |
switch_snmp_community |
SNMP v2c community string |
snmp_poll_interval |
Seconds between polls |
snmpwalk_bin |
Full path to snmpwalk binary |
trusted_mac_addresses |
Known/allowed MACs — case-insensitive, normalized at startup |
vendor_cache_file |
Path to persistent vendor cache JSON |
exporter_host |
Bind address for Prometheus exporter |
exporter_port |
Port for Prometheus exporter |
exporter_prefix |
Metric name prefix |
mail_* |
SMTP credentials and recipients |
Prometheus Metrics
Endpoint: http://<host>:<exporter_port>/metrics
Device presence
Single gauge reflecting the last SNMP readout as-is. Every MAC currently in the switch table is emitted with value 1. MACs from previous readouts that are no longer present are dropped. Between startup and the first successful poll no device series are emitted.
mac_watcher_device_present{mac="AA:BB:CC:DD:EE:FF",trusted="true"} 1
mac_watcher_device_present{mac="11:22:33:44:55:66",trusted="false"} 1
The trusted label reflects whether the MAC is in trusted_mac_addresses.
Exporter / cache statistics
mac_watcher_exporter_uptime_seconds
mac_watcher_exporter_requests_total
mac_watcher_snmp_polls_total
mac_watcher_vendor_cache_size
mac_watcher_vendor_cache_hits_total
mac_watcher_vendor_cache_misses_total
prometheus.yml example
scrape_configs:
- job_name: 'mac_watcher'
static_configs:
- targets: ['localhost:9200']
scrape_interval: 60s
Description
Languages
Python
100%