给OpenWrt路由器写个简易“设备管家”:用Shell脚本自动记录并通知新设备上线
OpenWrt智能设备监控用Shell脚本打造自动化网络管家家里智能设备越来越多路由器上显示的连接设备列表也愈发杂乱无章。作为技术爱好者我们总希望能第一时间知道哪些新设备接入了家庭网络——可能是朋友的手机也可能是孩子新买的智能手表甚至是可疑的未知设备。传统的手动刷新路由器管理页面显然不够优雅而OpenWrt这个开源路由器系统正好为我们提供了自动化监控的可能。本文将带你开发一个运行在OpenWrt上的设备管家脚本它能自动检测新接入的设备并通过多种方式实时通知你。不同于简单的设备列表查询这个方案实现了全自动化监控特别适合智能家居爱好者、小型办公室管理员或任何对网络安全有基本要求的用户群体。我们将从ARP和DHCP协议的工作原理入手逐步构建一个稳定可靠的监控系统。1. 监控原理与技术选型在OpenWrt系统上监控新设备接入主要有三种技术路线可供选择ARP缓存分析、DHCP租约监控和无线客户端列表。每种方法各有优劣理解它们的特性对构建可靠系统至关重要。ARP地址解析协议缓存是操作系统维护的IP地址到MAC地址的映射表。在OpenWrt中可以通过/proc/net/arp文件查看当前ARP缓存IP address HW type Flags HW address Mask Device 192.168.1.1 0x1 0x2 00:11:22:33:44:55 * br-lan 192.168.1.100 0x1 0x2 aa:bb:cc:dd:ee:ff * br-lan其中Flags字段的0x2表示设备当前在线。ARP监控的优点是响应快设备一接入网络就会出现在ARP表中缺点是缓存有时间限制通常几分钟不活跃设备会被移除。DHCP租约则是路由器分配给设备的IP地址记录存储在/tmp/dhcp.leases文件中1234567890 aa:bb:cc:dd:ee:ff 192.168.1.100 my-phone *这个文件包含租约到期时间、MAC地址、IP地址和设备名如果设备提供了主机名。DHCP监控的优势是信息更完整包含设备名且记录会持久保存到租约到期缺点是只有当设备请求或续约DHCP时才会更新。无线客户端列表可以通过iwinfo命令获取但只适用于无线连接设备。综合比较ARPDHCP组合方案最为全面可靠。2. 基础脚本开发与设备识别让我们从最简单的设备发现脚本开始。这个脚本将比较当前设备列表与之前保存的记录找出新增设备。首先创建存储已知设备数据库的文件KNOWN_DEVICES/etc/device_monitor/known_devices.db mkdir -p /etc/device_monitor [ -f $KNOWN_DEVICES ] || touch $KNOWN_DEVICES接下来是核心的对比函数使用DHCP租约文件作为数据源check_new_devices() { current_devices$(cat /tmp/dhcp.leases | awk {print $2,$3,$4}) while read -r mac ip name; do if ! grep -q $mac $KNOWN_DEVICES; then echo New device found: MAC$mac IP$ip Name$name echo $mac $ip $name $(date %s) $KNOWN_DEVICES fi done $current_devices }这个基础版本有几个明显问题设备改名会导致重复通知重启路由器会丢失/tmp/dhcp.leases文件。我们需要改进数据持久化方式# 改进的数据存储路径 PERSISTENT_STORAGE/etc/device_monitor/device_history.log LOG_ROTATE_SIZE1000 record_device() { local mac$1 ip$2 name$3 local timestamp$(date %Y-%m-%d %H:%M:%S) # 检查是否已有记录 local last_record$(grep ^$mac $PERSISTENT_STORAGE | tail -n1) if [ -z $last_record ]; then echo [NEW] $timestamp $mac $ip $name $PERSISTENT_STORAGE return 1 elif ! echo $last_record | grep -q $name; then echo [RENAME] $timestamp $mac $ip $name (was ${last_record##* }) $PERSISTENT_STORAGE return 2 fi return 0 } # 日志轮转检查 [ $(wc -l $PERSISTENT_STORAGE) -gt $LOG_ROTATE_SIZE ] { mv $PERSISTENT_STORAGE $PERSISTENT_STORAGE.old gzip $PERSISTENT_STORAGE.old }3. 增强可靠性ARP与DHCP双校验单纯依赖DHCP租约可能漏掉静态IP设备而仅用ARP缓存又缺少设备名信息。结合两者能显著提高监控可靠性。check_arp_table() { awk $30x2{print $4,$1} /proc/net/arp | while read mac ip; do local dhcp_info$(grep $mac /tmp/dhcp.leases) local name$(echo $dhcp_info | awk {print $4}) [ -z $name ] nameunknown if ! grep -q ^$mac $PERSISTENT_STORAGE; then record_device $mac $ip $name case $? in 1) handle_new_device $mac $ip $name ;; 2) handle_rename_device $mac $ip $name ;; esac fi done }实际部署时还需要考虑ARP缓存的时效性问题。OpenWrt默认ARP缓存超时时间为30秒到几分钟不等可以通过调整内核参数延长# 设置ARP缓存超时为1小时3600秒 echo 3600 /proc/sys/net/ipv4/neigh/default/gc_stale_time echo 3600 /proc/sys/net/ipv4/neigh/br-lan/gc_stale_time4. 通知系统集成与实践检测到新设备后及时通知非常重要。OpenWrt上常见的通知方式有邮件、Telegram Bot和LED指示灯。邮件通知配置示例send_email_notification() { local subject[OpenWrt] New Device Alert local bodyMAC: $1\nIP: $2\nName: $3\nTime: $(date) echo -e $body | msmtp -a default recipientexample.com }需要先安装msmtp和mailx包并配置SMTP服务器信息。Telegram Bot通知更实时TELEGRAM_BOT_TOKENYOUR_BOT_TOKEN TELEGRAM_CHAT_IDYOUR_CHAT_ID send_telegram_notification() { local message*New device detected!* MAC: \$1\ IP: $2 Name: $3 Time: $(date) curl -s -X POST \ -H Content-Type: application/json \ -d {\chat_id\:\$TELEGRAM_CHAT_ID\,\text\:\$message\,\parse_mode\:\Markdown\} \ https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage /dev/null }物理LED提示适合快速响应blink_led() { local led/sys/class/leds/tp-link:blue:wps local original_brightness$(cat $led/brightness) for i in 1 2 3; do echo 1 $led/brightness sleep 0.5 echo 0 $led/brightness sleep 0.5 done echo $original_brightness $led/brightness }不同路由器LED路径可能不同需要根据实际硬件调整。5. 生产环境部署与优化开发完成后我们需要将脚本部署为定期运行的监控服务。OpenWrt的Cron是最简单的调度方案# 安装必要的软件包 opkg update opkg install cron msmtp curl # 添加每5分钟执行一次的定时任务 (crontab -l 2/dev/null; echo */5 * * * * /usr/bin/device_monitor.sh) | crontab -完整的脚本应该包含错误处理和日志记录LOG_FILE/var/log/device_monitor.log MAX_LOG_SIZE1048576 # 1MB log() { echo $(date %Y-%m-%d %H:%M:%S) - $1 $LOG_FILE } # 日志轮转 [ $(stat -c%s $LOG_FILE 2/dev/null || echo 0) -gt $MAX_LOG_SIZE ] { mv $LOG_FILE $LOG_FILE.old gzip $LOG_FILE.old } # 主程序 main() { log Starting device monitoring check_arp_table log Monitoring completed } main $对于更复杂的部署可以考虑将这些功能打包为OpenWrt软件包# Makefile示例 include $(TOPDIR)/rules.mk PKG_NAME:device-monitor PKG_VERSION:1.0 PKG_RELEASE:1 include $(INCLUDE_DIR)/package.mk define Package/device-monitor SECTION:net CATEGORY:Network TITLE:Device Monitoring Service DEPENDS:msmtp curl endef define Package/device-monitor/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) ./files/device_monitor.sh $(1)/usr/bin/ $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/device_monitor.init $(1)/etc/init.d/device_monitor endef $(eval $(call BuildPackage,device-monitor))6. 高级功能扩展基础监控实现后可以考虑添加更多实用功能设备分类与友好命名# /etc/device_monitor/device_categories.conf aa:bb:cc:*:*:* smartphone 家庭手机 00:11:22:*:*:* iot 智能家居设备流量监控集成# 获取设备当日流量需要安装vnstat get_device_traffic() { local mac$1 local ip$(grep $mac $PERSISTENT_STORAGE | awk {print $2} | tail -n1) vnstat --dumpdb | grep $ip | awk -F\; {print $4,$5} }可疑设备检测check_suspicious_device() { local mac$1 local oui$(echo $mac | cut -d: -f1-3 | tr -d :) # 检查MAC厂商是否在已知列表中 if ! grep -q ^$oui /etc/device_monitor/known_oui.txt; then send_telegram_notification Suspicious device detected!\nMAC: $mac return 1 fi return 0 }7. 可视化与历史数据分析长期运行的监控系统会产生大量有价值的数据简单的日志分析就能提供丰富洞察# 生成最近一周的设备连接报告 generate_weekly_report() { local start_date$(date -d 7 days ago %Y-%m-%d) local end_date$(date %Y-%m-%d) echo Device Connection Report ($start_date to $end_date) echo awk -v start$start_date -v end$end_date $1 start $1 end { if ($2 [NEW]) count[$4] } END { print New devices per day: for (date in count) { print date, count[date] } } $PERSISTENT_STORAGE }对于更复杂的分析可以将数据导出到外部系统# 导出到InfluxDB进行可视化 export_to_influxdb() { local mac$1 ip$2 name$3 curl -i -XPOST http://localhost:8086/write?dbnetwork \ --data-binary devices,hostrouter,mac$mac,ip$ip,name$name status1 $(date %s%N) }这个OpenWrt设备管家项目展示了如何用简单的Shell脚本实现实用的网络监控功能。从最初的设备发现到完整的通知系统再到高级分析和可视化每个阶段都能根据实际需求灵活扩展。