☰
WiFi探针报警实战:原理、实现与避坑指南
2026/10/15 15:53:00 网站建设 项目流程

简介:《WiFi_alarm项目报告1》是一份面向计算机网络、物联网及机器学习交叉领域学习者的课程项目报告,聚焦如何利用Wi-Fi信道状态信息(CSI)与机器学习构建环境异常感知系统。报告从项目背景、国内外研究现状出发,系统梳理了Wi-Fi CSI的概述、特性与采集方法,并给出了“WiFi Alarm”系统的概要设计,包括数据采集模块、特征处理模块和异常检测模块的划分;详细设计部分则进一步落到CSI信息采集与实时分析、数据预处理与特征选取、机器学习算法选择及SVM分类训练与预测等环节,并涉及硬件/软件环境、训练数据采集等实操细节,便于读者从零搭建类似环境感知项目并完成实验。资源包为单个PDF文件,大小约3.19MB,目录结构清晰,包含绪论、技术理论、概要设计、详细设计等完整章节,适合作为课题设计、课程汇报或入门研究的重要参考资料。该资源已有117人学习浏览,是一份结构完整、可直接对照学习的项目报告,从理论到实现均给出清晰脉络,尤其适合需要快速理解CSI采集与机器学习异常检测结合方式的读者。

1. WiFi_alarm 项目报告1:用 WiFi 探针做报警,第一期的关键结论

某安防需求里,客户要求在设备间无人值守的时段判断“有没有人进来”。红外误报多,摄像头有盲区,最终落地方案是 WiFi 探针报警。这份报告记录的是这个方向的第一期成果:只要设备开了 WiFi,即使没有连接任何路由器,也会周期性地发出探测请求帧。被动监听这些帧,就能在目标完全无感的情况下判断“某个 MAC 地址出现了”,再结合时间段和区域规则触发报警。适合做物联网报警、低功耗安防、机房巡检的从业者参考,结论明确:这条路可行,但坑集中在 MAC 随机化、信道覆盖和误报打磨上,提前知道比上线后返工划算得多。

2. 为什么报警方案选 WiFi 探针:三条路线的对比与选型依据

2.1 报警信号的基础:Probe Request 与被动监听

手机或物联网设备开启 WiFi 但没有连接任何 AP 时,会周期性地发送探测请求帧,也就是 Probe Request,目的就是在环境里“问”有哪些可用的网络。帧头里带着发送者的 MAC 地址,这就是我们判断“设备在场”的核心依据。即使设备已经连上了某个 AP,它仍会不定期重新探测其他信道,所以探测请求几乎不可能完全消失,这给被动监听提供了稳定的信号源。

被动监听的意思是网卡只接收、不发送,不主动和任何设备握手,也不参与网络关联。相比主动探测方案,它不产生额外射频信号,不会干扰现场,也不依赖目标设备做出任何响应。对安防场景来说,这个特性很关键:探测对象不会有感知,部署位置也没有“必须连入指定网络”的约束。设备只要开着 WiFi,从口袋里掏出来、走进探测范围,就会被记录一次出现事件。

实现上,普通网卡默认关联模式只能收到发给自己的帧,需要把无线网卡切到监听模式才能看到空中所有 802.11 帧。常见做法是使用支持 monitor mode 的 USB 无线网卡,接在树莓派或普通开发板上,配合抓包脚本过滤出 subtype 为 4 的 Probe Request 帧。这一层打通之后,后面的设备识别和报警规则才有数据可用。

2.2 三条路线对比:RSSI 门限、连接状态与探针存在性

做 WiFi 报警,业内常见的方案有三条路线,我按适用场景和误报特性做了对比,如下表所示。

路线感知方式目标是否需配合误报来源部署成本典型场景
RSSI 门限监听信号强度突变不需要人体遮挡、多径衰落最低门口人员经过感应
WiFi 连接状态目标接入自家 AP必须连入指定网络访客接入、漫游切换低访客管理、设备在线监测
探针存在性被动监听 Probe Request不需要随机 MAC、路过车辆中无人值守区域、周界报警

RSSI 门限方案的原理是布一个探测点,连续采样周边信号强度,当数值出现明显跳变时认为有人或移动物体靠近。优点是成本极低,一个开发板加全向天线就能跑;缺点是信号强度本身受人体遮挡、金属门、多径反射影响大,很难区分“有人经过”和“信号波动”,误报率在复杂环境里偏高。

WiFi 连接状态方案判断的是设备是否连入了自己部署的 AP。可靠性高,但适用面窄:探测对象必须主动连接你的网络,这天然限制了它只能用于访客管理或内部设备在线监测,做不了“不配合人员的闯入报警”。探针存在性方案虽然要忍受随机 MAC 带来的识别困难,但它不要求目标做任何事,覆盖范围也比 RSSI 方案大得多。项目第一期的主路线选的是探针存在性,RSSI 作为辅助联动,用于确认目标是否真的在靠近某个边界。

2.3 硬件选型与天线:从 MCU 到树莓派的取舍

硬件层面,探测端有三个常见选择:带 WiFi 的 MCU 开发板、树莓派类单板电脑、普通路由器刷第三方固件。对报警项目来说,三者的核心差异在算力、可维护性和抓包能力,如下表。

硬件算力监听模式支持功耗维护成本推荐优先级
MCU 开发板弱,适合简单过滤部分芯片支持极低固件烧录较繁琐固定点位、低功耗场景
树莓派类单板强,可跑分析脚本配 USB 网卡即可中等系统级维护,方便远程首选
普通路由器 + 第三方固件中等取决于驱动中等黑匣子,不易排错不推荐

我一般会优先选树莓派类单板加 USB 无线网卡,理由有两点:一是 scapy 这类抓包分析库在 Linux 上直接可用,写脚本调试方便;二是探测逻辑后续要加白名单、时间段规则、上报逻辑,跑在通用系统上比交叉编译 MCU 固件快得多。MCU 方案适合站点数量大、供电受限的场景,但调试和固件升级成本会摊到每个点位。

天线选择上,室内设备间和机房推荐 2dBi 左右的全向天线,贴近部署、覆盖半径十米内足够;边界或走廊场景用 6dBi 定向天线,把探测区域压窄,减少横向干扰。这里有个常见误区:天线增益越高越好。实际上增益提升的是某个方向的覆盖,代价是其他方向的探测能力下降,部署方向反了就变成“漏报放大器”。第一期项目建议先把天线放在固定位置,用信号覆盖测试确认探测半径,而不是直接调高增益。

3. 把 WiFi_alarm 跑起来:探针采集、设备识别与报警触发

3.1 监听 Probe Request 的最小程序

先做最基础的一步:让探测端能持续收到 Probe Request,并把 MAC 地址、信号强度、时间戳打印出来。我在树莓派上常用 Python 加 scapy 库实现,网卡先切到监听模式。切网卡的命令如下。

# 查看无线网卡接口名 iw dev # 新建监听模式接口,wlan0 替换为实际接口名 sudo iw phy phy0 interface add mon0 type monitor # 启动监听接口 sudo ip link set mon0 up # 把物理网卡从关联模式断开,避免同时收发普通数据 sudo ip link set wlan0 down

切完监听模式后,物理网卡不再参与正常的 WiFi 连接,网络会暂时中断,这是正常现象。远程操作时要注意:一旦执行了上面的命令,SSH 连接可能立刻断开,最好用有线网络或提前写好自启脚本。接下来运行抓包脚本。

from scapy.all import * # 需要监听的接口名,与上一步创建的 mon0 对应 IFACE = "mon0" def handle_probe(pkt): # 只处理 802.11 管理帧中的 Probe Request if pkt.haslayer(Dot11ProbeReq): # 提取源 MAC 地址 mac = pkt.addr2 # 提取信号强度,单位为 dBm rssi = pkt.dBm_AntSignal if hasattr(pkt, "dBm_AntSignal") else None print(f"{mac} | RSSI: {rssi} dBm") # 开始监听,store=0 表示不缓存数据包 sniff(iface=IFACE, prn=handle_probe, store=0)

这段脚本的核心逻辑只有两步:用sniff从指定接口抓包,在回调函数里判断是不是 Probe Request,是就把 MAC 和信号强度打出来。sniff(iface=IFACE, prn=handle_probe, store=0)里的prn参数指定每收到一个包调用的处理函数,store=0防止内存里堆积无用的包对象,长时间运行时必须加上,否则跑几天内存就被撑爆。

参数说明:IFACE要改成实际创建的监听接口名;dBm_AntSignal是否可用取决于网卡驱动,部分网卡不支持,这种情况下 RSSI 会是空值。如果你发现脚本能收到帧但 RSSI 都是 None,不要纠结,先用 MAC 存在性做判断。

3.2 设备去重与白名单:先解决“谁进来了”

原始抓包数据里,同一台设备一分钟内可能会被捕获几十次。直接拿去触发报警会产生大量重复事件,所以要做设备去重和设备表维护。常见的做法是用一个字典保存设备状态,键是 MAC 地址,值包含最后出现时间和累计出现次数。

from collections import defaultdict import time # 设备表:MAC -> {last_seen, count} devices = defaultdict(lambda: {"last_seen": 0, "count": 0}) # 设备超过该秒数未出现,则认为已离开 TIMEOUT = 60 # 累计出现次数达到该值才认为设备“在场” CONFIRM_COUNT = 3 def on_probe(mac, rssi): now = time.time() info = devices[mac] # 更新最后出现时间和出现次数 info["last_seen"] = now info["count"] += 1 # 清理超时设备 for m in list(devices.keys()): if now - devices[m]["last_seen"] > TIMEOUT: del devices[m] # 设备连续多次出现才输出“在场”事件 if info["count"] >= CONFIRM_COUNT: print(f"present: {mac}")

这段代码里,devices[mac]默认值用lambda构造,保证每个新出现的 MAC 都从零计数开始。CONFIRM_COUNT = 3是防止单次杂散信号导致的误判,至少要连续捕获到 3 次才算设备在场,这个值可以根据环境密度调整。清理超时设备的逻辑必须在每次回调里跑,否则设备表无限膨胀,长时间运行会越来越慢。

白名单逻辑建议加在这层之后:先判断 MAC 是否在白名单里,不在才输出事件。之所以用白名单而不是黑名单,是因为报警场景里“已知可信设备”往往是少数,白名单可以把保洁、运维人员的设备直接放行,剩下的未知设备才值得报警。黑名单的问题是永远列不全,环境里总有不认识的设备会频繁出现。

{ "whitelist": ["aa:bb:cc:dd:ee:ff", "11:22:33:44:55:66"], "timeout_seconds": 60, "confirm_count": 3 }

注意:如果现场都是手机,白名单会因 MAC 随机化而失效。这个问题在第 4 章展开,这里只说结论——部署前先观察一段时间环境里的 MAC 特征,再决定白名单策略。

3.3 报警决策:时间段、去抖与区域联动

设备识别通过后,报警决策要解决三个问题:什么时间报警、连续几次才报、单个探测点能不能确信。我把这三个问题拆成三个可配置参数,放在决策逻辑里。

时间段规则解决的是“合法在场”和“非法闯入”的区分。设备间晚上 10 点到早上 6 点不应有人,这段时间任何新设备出现都应触发报警;白天有人巡检,就不报。实现上只需要比对当前时间和配置的静默时段。

去抖逻辑解决的是误报。单次探测受信道丢帧、设备短暂开关 WiFi 影响很大,常见做法是要求设备在一个时间窗口内出现 N 次以上,且窗口内持续存在超过 M 秒,才认为是一次有效出现。参数设置参考下表。

参数建议值作用
确认次数3 ~ 5 次过滤瞬时杂散帧
时间窗口10 ~ 30 秒限定确认次数的统计周期
离场超时60 ~ 120 秒设备消失多久后判定离开
RSSI 门限-75 dBm 左右过滤探测范围外的弱信号设备

区域联动是降低误报的最后一层保障。点位多的现场,可以设置“两个相邻探测点同时检测到同一设备才报警”。走廊一端信号泄露可能让探测点误判,但两个点同时误判的概率很低。第一期项目里我用的规则是:单点触发记一次“可疑”,两点联动触发才真正报警,报警后通过 webhook 推给钉钉或企业微信机器人,格式如下。

def should_alarm(present_devices, region_id): # present_devices: 当前满足在场条件的设备列表 # region_id: 区域标识,用于关联点位 if not present_devices: return None # 至少两个点位确认才触发报警 confirmed_points = set() for dev in present_devices: confirmed_points.add(dev["point_id"]) if len(confirmed_points) >= 2: return { "region_id": region_id, "devices": [d["mac"] for d in present_devices], "timestamp": int(time.time()), "level": "high" } return None

这段决策逻辑里,confirmed_points是一组点位编号的集合,只有去重后的点位数量大于等于 2 才返回报警事件。单点方案可以把>= 2改成>= 1,但我建议至少保留“去抖 + 时间段”两层过滤,否则误报会消耗大量排查精力。

4. WiFi_alarm 调试避坑:误报、漏报与随机 MAC 的实战记录

4.1 几乎收不到探针:网卡监听模式没生效

现象:设备就在探测点旁边,手机 WiFi 开着,但控制台一个 Probe Request 都打不出来。原因排查后发现网卡根本没有进入监听模式,iw dev显示接口仍然是 managed 状态。很多 USB 网卡驱动默认不支持 monitor mode,即使接口建出来了,底层驱动也没有真正切换到监听状态。

解决:先换一张确认支持监听模式的网卡芯片。常见做法是先跑iw phy phy0 info查看驱动支持的接口模式,如果列表里只有 managed 而没有 monitor,立刻换网卡,不要再浪费时间调参数。确认支持之后,用iw dev mon0 set channel 6把信道固定到目标设备所在信道,或者在脚本里做信道轮询。否则网卡默认停在某个不相关的信道上,自然什么都收不到。

4.2 手机 MAC 随机化导致白名单失效

现象:同一台手机今天显示一个 MAC,明天又换一个,白名单里该设备的固定地址完全匹配不上。原因是从新版本系统开始,手机在主动探测时默认使用随机 MAC,甚至每次扫描都会变化。这是探针方案里最让人头疼的问题,几乎没有完美解。

解决分三种场景处理。场景一是目标设备是自己的资产,比如巡检终端,可以关闭这些设备的随机 MAC,并配置固定白名单。场景二是报警对象是陌生人的手机,此时不要依赖精确 MAC 匹配,而是按厂商 OUI 前缀做粗分类,或者干脆只关注“陌生设备出现了多少台”。场景三是现场固定 AP 覆盖的区域,可以要求目标设备先连入指定 AP,用关联记录代替探针识别——这又回到第 2 章的路线 B,说明选型时就要预估 MAC 随机化的影响。

4.3 误报率居高不下:周围常驻设备反复触发

现象:门窗没有异常,系统却频繁报警。排查发现报警设备来自邻居的打印机和智能音箱,它们虽然不在探测范围内,但信号的反射和天线旁瓣让探测端偶尔收到弱信号。原因是没有对周围常驻设备做基线记录,也没有限制信号强度门限。

解决:部署后先静默观察 24 小时,把所有出现的 MAC 和 RSSI 分布记录下来,把稳定出现的设备加入白名单。同时调高 RSSI 门限到 -75 dBm 以上,丢弃远距离弱信号。经验值是在办公室环境,-75 dBm 大致对应五六米半径,超过这个范围的信号直接忽略。

4.4 长时间运行后停止上报:内存与 USB 休眠的双重问题

现象:探测端刚部署时运行正常,跑了超过一天后不再上报任何事件,重启进程后恢复。排查后发现两个叠加原因:scapy 的sniff默认会缓存包,store=0没写时内存持续增长,触发了系统 OOM;部分 USB 网卡在长时间无流量后会进入省电休眠,不再接收数据。

解决:脚本里强制store=0,并用 systemd 服务做守护,进程异常退出时自动重启。同时禁用网卡的 USB 自动挂起,在 systemd 服务里配置重启策略,保证探测端连续运行。以下是常见的服务配置片段。

# /etc/systemd/system/wifi-alarm.service [Unit] Description=WiFi Alarm Probe After=network.target [Service] ExecStart=/usr/bin/python3 /opt/wifi_alarm/probe.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target

配置里Restart=always是关键,进程无论因为什么原因退出都会在 10 秒后重启。配合脚本内部的store=0,可以稳定扛住数周不重启。

4.5 信道拥挤导致漏报:2.4G 环境下的丢帧

现象:探测点部署在 AP 密集的办公区,周围有十几个 WiFi 网络,抓包数量看起来很多,但某一台测试手机连续走进走出,漏报率很高。原因是在 2.4GHz 频段,AP 和探针共用同一频谱,AP 的广播帧和数据帧占用了大量信道时间,Probe Request 作为低优先级帧大量被冲突丢弃。

解决:一是改用支持 5GHz 监听的网卡,把探测信道放在 5GHz 低频段,那里的环境通常比 2.4G 干净得多;二是部署多个探测点做交叉验证,即使单点丢帧率高达 30%,两个点同时漏掉同一设备的概率就降到 10% 以下。这也是我在第 3 章坚持做多点位联动的原因——它不只是防误报,也在弥补漏报。

5. 验证方法:把 WiFi_alarm 从原型推向可验收状态

到这一步系统已经能跑,但离“验收”还有一段距离。我的验证方法是做一次受控盲测:准备三台已知 MAC 的设备,分别关闭随机 MAC,在探测点覆盖范围内完成规定的走动路线,同时安排一个人在后台记录真实出现时间段,最后对比系统检出结果。

建议的验收指标如下表。

指标计算方式验收标准
检出率系统检出次数 / 真实出现次数≥ 95%
误报率无目标时段报警次数 / 总测试时长≤ 1 次/小时
报警延迟首次探测到设备到触发报警的间隔≤ 15 秒
连续运行稳定性系统连续运行不崩溃的时长≥ 72 小时

测出数据后,重点观察误报项的来源:是随机 MAC 让同一设备变成了多个 ID,还是 RSSI 门限过低带入了环境干扰。逐项修正参数后再跑一轮,直到满足上述标准。

进阶方向上,第一期之后有三个值得做的点。第一是行为基线:记录每个 MAC 出现的时间分布,让系统在一周后自动识别“这个设备本来就会在这个时段出现”,进一步压低误报。第二是和摄像头联动:探针报警触发录像标记,调取录像时直接跳到报警时间点,省去翻录像的功夫。第三是低功耗化:把树莓派替换成 MCU 方案,部署到电池供电的边界点位,扩大覆盖范围。

最后说一个教训。当时我在某个模拟项目 X 里,因为赶进度直接上了探针方案,没有事先统计环境里 MAC 随机化的情况,结果白名单策略上线第一天就整体失效,报警事件混杂着大量陌生随机地址,排查花了两天。后来把所有识别逻辑改成“白名单精确匹配 + 陌生设备计数 + 点位联动”三层结构才稳定下来。先把环境基线测清楚,再谈报警准确性,这条路能少走很多弯路。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询