2026-05-11: Notifying of new network devices in pfSense
(This article is also available via the short link tomrei.ch/pfsense-newdevices)
For years, I've been looking for a simple way to get notified when a new device connects to my network. I've tried various pfSense plugins over the years, but they've all had drawbacks of one kind or another. The most recent one I was using stopped working properly when I switched to the Kea DHCP server.
I finally sat down with Claude Opus 4.6 and together we wrote a simple script that does exactly what I want: the first time it sees a MAC address it has never seen before, it sends a Pushover notification. That's it. Super simple, works great, nothing overkill.
Here's the script:
#!/bin/sh
# detect_new_devices.sh
# Monitors the ARP table on pfSense for new (never-before-seen) devices.
# Sends a Pushover notification when a new MAC address appears.
#
# SETUP:
# 1. Copy this script to /usr/local/etc/detect_new_devices.sh on your pfSense box.
# 2. chmod +x /usr/local/etc/detect_new_devices.shsr
# 3. Edit the PUSHOVER_USER_KEY and PUSHOVER_API_TOKEN below.
# 4. Add a cron job (via pfSense GUI or crontab):
# */1 * * * * /usr/local/etc/detect_new_devices.sh
# (runs every 1 minute; adjust as desired)
#
# FILES:
# /usr/local/etc/known_devices.txt - persistent list of seen MAC addresses + when
# /usr/local/etc/new_device.log - log of all new-device detections
# ---- Configuration ----
PUSHOVER_USER_KEY="ENTER USER KEY HERE"
PUSHOVER_API_TOKEN="ENTER API TOKEN HERE"
KNOWN_DEVICES_FILE="/usr/local/etc/known_devices.txt"
LOG_FILE="/usr/local/etc/new_device.log"
# ------------------------
# Create files if they don't exist
touch "$KNOWN_DEVICES_FILE"
touch "$LOG_FILE"
# Parse ARP table: extract IP and MAC pairs for entries that are valid (not incomplete)
arp -an | grep -v incomplete | awk -F'[() ]' '{
for (i=1; i<=NF; i++) {
if ($i ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) { ip=$i }
if ($i ~ /^([0-9a-f]{2}:){5}[0-9a-f]{2}$/) { mac=$i }
}
if (ip != "" && mac != "") { print mac, ip; ip=""; mac="" }
}' | while read mac ip; do
# Normalize MAC to lowercase
mac=$(echo "$mac" | tr 'A-F' 'a-f')
# Check if MAC is already known
if ! grep -qi "^$mac " "$KNOWN_DEVICES_FILE"; then
timestamp=$(date "+%Y-%m-%d %H:%M:%S")
# Try to get hostname via DNS reverse lookup
hostname=$(host "$ip" 2>/dev/null | awk '/domain name pointer/ {print $NF}' | sed 's/\.$//')
if [ -z "$hostname" ]; then
hostname="(unknown)"
fi
# Record device
echo "$mac $ip $timestamp $hostname" >> "$KNOWN_DEVICES_FILE"
echo "$timestamp NEW DEVICE: MAC=$mac IP=$ip HOST=$hostname" >> "$LOG_FILE"
# Send Pushover notification
/usr/local/bin/curl -s \
--form-string "token=$PUSHOVER_API_TOKEN" \
--form-string "user=$PUSHOVER_USER_KEY" \
--form-string "title=New Device on Network" \
--form-string "message=MAC: $mac
IP: $ip
Hostname: $hostname
First seen: $timestamp" \
--form-string "priority=0" \
https://api.pushover.net/1/messages.json > /dev/null 2>&1
fi
done
And the crontab entry to run it on a schedule:
*/1 * * * * /usr/local/etc/detect_new_devices.sh