☰
netdiscover实战:基于ARP的局域网设备发现与资产盘点
2026/9/25 23:30:00 网站建设 项目流程

简介:Netdiscover 是一款开源的 ARP 扫描与网络地址发现工具,专为无 DHCP 的无线网络设计,通过发送 ARP 请求并监听响应来探测活动设备及其 IP、MAC 地址,适合网络管理员、安全审计人员用于监控、排障和入侵检测,也适合入门者学习 ARP 协议与网络扫描原理。该安装包共 39 个文件,约 359KB,主体为 C 语言源码(.c / .h)及自动构建脚本(configure、Makefile、spec 等),涵盖数据请求/响应、界面处理、OUI 数据库更新等模块,便于用户按需编译与二次开发;src 目录按功能拆分,结构清晰,对理解网络工具的开发方式很有帮助。压缩包还包含 ChangeLog、README、AUTHORS 等文档,可快速了解版本演进与使用方式。目前已有 262 人学习下载。获取后可结合 nmap、ettercap 进行网络评估,也可参考其 ARP 触发逻辑与多网卡交互实现,提升无线环境下的网络资产发现效率。

1. netdiscover:一条 ARP 命令把局域网主机全部翻出来

排查网络时最烦的一种情况:明明设备连着网,路由器后台里能看到,但你想 SSH 上去改配置却不知道它的 IP;或者办公室里多了个陌生设备,你想确认它接在哪台交换机下面。用 ping 扫段会漏掉开了防火墙的主机,用 Nmap 扫端口动静又太大。netdiscover 这个开源项目就是专门干这个的:它直接基于 ARP 协议做探测,只要设备和你处在同一个二层网络并且活着,基本都会应答,响应速度快、命令简单、输出里直接带 MAC 厂商信息,一眼能认出是什么设备。实际用下来,一个 /24 网段从执行到出结果不到两秒,适合网管做内网资产盘点,也适合开发者在实验室排查设备连线问题。这篇笔记我把它的协议原理、参数细节、输出重放、常见坑和长期监听探针写法完整过一遍。

2. 先搞清楚 ARP 再谈扫描:协议原理与工具选型

2.1 ARP 请求广播、响应单播:netdiscover 依赖的发现机制

局域网里两台设备通信前,发送方只知道对方的 IP,不知道对方的 MAC 地址,这时就得靠 ARP(Address Resolution Protocol)。设备发出一个广播帧,问"谁是这个 IP?把你的 MAC 告诉我",这个广播会到达同一二层域内的所有主机;被问到的那台主机回一个单播 ARP 响应,把自己的 MAC 地址填进包里。netdiscover 的工作原理就是围绕这个交互过程展开的。

主动扫描时,netdiscover 遍历你给定的 IP 范围,逐个构造 ARP 请求包发出去,等待响应的同时记录应答者的 IP 和 MAC。由于 ARP 请求是广播帧,只要目标主机在线且没有做特殊过滤,就会毫无条件应答——这正是它比 ICMP ping 扫段更可靠的原因:Windows、Linux、打印机、摄像头、IoT 设备对 ARP 请求的响应不需要经过应用层,防火墙一般也不会拦 ARP 报文。我拆过好几个开源网络工具,这是唯一一个能稳定覆盖"防火墙全开但网络正常"场景的命令行工具。

被动模式则反过来:netdiscover 不主动发包,只把网卡设为混杂模式,监听局域网里其他人产生的 ARP 请求和响应。好处是完全不产生流量,适合放在接入层交换机旁观察设备间通信;代价是只能看到"别人在互相通信时"暴露的 IP-MAC 映射,如果两台设备长时间不通信,被动模式就发现不了它们。

2.2 主动与被动两种模式:用在哪类排查场景更合适

主动模式解决"这个网段里到底有哪些设备"的问题。典型场景是维护一个无人值守的机柜:设备上线后 IP 总是变,拿 netdiscover -r 192.168.1.0/24 扫一轮,所有活着的设备全部列出来,按 MAC 厂商匹配设备型号。处理 /24 时我用默认参数就够,但扫更大的网段时要注意发包节奏和超时时间,下面一章会细说参数含义。

被动模式解决"这个接口下产生了哪些通信"的问题。比如新部署了一套开源监控系统,怀疑某台设备在定时向外部发心跳包,把 netdiscover 挂成被动模式跑半小时,就能抓到那台设备的 IP 和 MAC。另一个常见用法是排查私接路由:办公网里有人私接了一个小路由器,管理员的扫描是扫不出来的,但被动监听能捕获客户机上行的 ARP 请求,进而发现网关 MAC 变了。

2.3 和 arp-scan、Nmap 的边界:什么时候不该用 netdiscover

先划一条边界:netdiscover 只工作在二层,跨网段扫描对它毫无意义。你要扫三层以上的设备或远端子网,应该用 Nmap 的 ICMP 或 TCP 探测,netdiscover 在这个场景下没有用武之地。与 arp-scan 比,两者同为 ARP 扫描工具,但 arp-scan 输出更简洁、适合脚本处理;netdiscover 的优势是提供了可交互的字符界面、被动监听模式和结果重放功能,后者在"长期监听、事后分析"这个场景下更顺手。我的选择标准是:一次性快速盘点用 arp-scan,需要看实时结果、长期监听和重放历史扫描结果时用 netdiscover。

还有个容易翻车的认知:netdiscover 只告诉你"这台 IP 有响应",不代表这台设备就一定在线。某些网卡或驱动会对 ARP 请求做代理应答,把不在线的地址也回出去;如果只依赖一次扫描就做资产下线判断,会得到错误结论。正确做法是连续多轮扫描做交叉确认,或者用 Nmap 对候选 IP 做端口探测补一步验证。

3. 安装与首轮实测:三种装法 + 一组直接可用的扫描命令

3.1 包管理器安装与源码编译:按你的系统选路径

netdiscover 是 GitHub 上的开源项目,开发者自己维护了一套源码包。最常见的是 Debian/Ubuntu/Kali 系的 apt 源,直接安装最省事,装完就有命令。macOS 用户可以用 Homebrew,不过 brew 里的版本偶尔滞后于主线;如果要用最新代码就 clone 源码自己编。

# Debian / Ubuntu / Kali 系 sudo apt update sudo apt install -y netdiscover # macOS Homebrew brew install netdiscover

源码编译的方式适合嵌入式平台和需要定制参数的场景。netdiscover 依赖 libpcap,源码编译之前先把依赖装好,再走标准的 autoreconf 和 configure 流程。我编译它的原因是想在交叉编译环境里生成 ARM 版本,放到嵌入式设备上做局域网探针用。

git clone https://github.com/alexxy/netdiscover.git cd netdiscover sudo apt install -y libpcap-dev autoconf automake autoreconf -i ./configure --prefix=/usr/local make && sudo make install

configure 加 --prefix 指定安装路径,默认装到 /usr/local/bin。如果只想在编译后临时跑而不想安装,编译完直接调用 src/netdiscover 也可以。编译期间最常见的报错是缺 libpcap-dev,按提示装上即可。

跑任何操作前都要确认自己有 root 权限。ARP 请求需要构造原始 socket,普通用户执行会直接报权限错误,这是新手最容易卡住的地方。装完先执行下面这条命令验证环境正常,能在屏幕上看到实时滚动的 ARP 流量再继续调参。

sudo netdiscover -p -i eth0

这里 -p 是进入被动监听模式,-i eth0 指定监听网卡。看到不断在屏幕上刷出 ARP 数据包就说明 libpcap 工作正常。看不到任何输出先别急着调整命令,大概率是网卡没开混杂模式或者接到了一个没流量的接口上,这个问题我放在避坑章节细说。

3.2 主动扫描命令:CIDR 范围、发包节奏与参数对照

主动扫描是使用频率最高的模式。最标准的用法是直接用 CIDR 指定网段,netdiscover 会把整个子网的主机挨个发 ARP 请求探测,响应结果聚合后显示在屏幕上,底部会动态更新已发现的设备数和响应时间。

sudo netdiscover -i eth0 -r 192.168.1.0/24

执行后界面顶部显示当前扫描范围和已发现的主机数,每行一台设备:IP 地址、MAC 地址、MAC 所属厂商。几十台上网设备的办公网扫一轮大概三秒内完成,极端大的网段或高延迟链路下时间会长一些。如果只是想快速确认某个 IP 是否存在,可以把范围写成单 IP 区间,比如 -r 192.168.1.1-192.168.1.50,扫描范围更小、速度更快、结果更聚焦。

参数里有几个影响结果的细节需要注意。下面是我整理的核心参数对照表,这几个参数共同决定了"能不能扫到、扫得快不快、漏不漏"三个结果。

参数作用默认值调参建议
-i指定监听网卡自动选择多网卡机器必须显式指定,否则可能扫错虚拟网卡
-r指定扫描范围,支持 CIDR 和区间写法无/24 起步,超过 /16 建议分段扫描
-c每台主机发送的 ARP 请求数量3无线环境、弱信号环境调到 5-7 更稳
-t两个 ARP 请求之间的间隔(毫秒)100链路差时调到 150-200,低于 50 容易丢响应
-s每轮扫描结束后的额外睡眠时间(微秒)30000一般不用调,批量扫描太多网段时加大到 100000
-L将扫描结果输出到文件,供后续重放无建议养成习惯,资产盘点务必落盘
-n扫描到第几个 IP 后停止无调试用,验证编包逻辑或定位某个 IP 时用

-c 和 -t 是影响扫描结果质量的核心参数。ARP 请求是广播发出的,响应是否被网卡及时收回来取决于链路状态和系统协议栈处理速度。Wi-Fi 环境下发包间隔太短,响应还没回来下一轮广播又出去了,网卡驱动丢帧,部分设备会被漏掉;有线网络下默认值 100 毫秒没问题,但扫旧式嵌入式设备时,它们的协议栈慢,需要加大 -c 和 -t 才有把握全部发现。

3.3 被动监听命令:先开混杂模式再抓 ARP 流量

被动模式的关键在于:在运行 netdiscover -p 之前,确认网卡处于混杂模式。虽然 netdiscover 内部也会尝试把网卡设为混杂模式,但部分 USB 网卡驱动并不支持,或者系统权限配置导致设置失败,建议手动设置并把硬件状态打印出来做双重确认。

sudo ip link set eth0 promisc on sudo ip link show eth0 | grep PROMISC sudo netdiscover -p -i eth0

第一条命令打开混杂模式,grep 确认输出中出现了 PROMISC 字样,说明网卡确实工作在混杂状态,第三步的 netdiscover 才有效。如果 grep 没输出,说明网卡不支持,要么换网卡,要么接受"只能看到属于本接口的流量"的退化结果。

被动模式下的输出和主动模式不太一样:屏幕上会不断滚动显示捕捉到的 ARP 请求和响应,包含源 IP、源 MAC、目标 IP、目标 MAC 和包类型。这些数据能反映设备间的通信关系,而不只是"某台设备存在"。对长期探针来说,被动模式最大的价值是零流量干扰——放在接入交换机旁跑上一整天,对现有业务没有任何影响,却能持续记录所有设备的活动。

被动模式还有个容易被忽视的用途:观察新设备接入。主动扫描只有在你执行的那一个瞬间才有结果,新设备接入后如果没有立刻跑一轮主动扫描,就会被遗漏。把被动模式配合 -L 参数挂后台写日志,设备接入时产生的 ARP 广播会被完整记录,之后回头查日志就能定位接入时间点。这个玩法我在第 6 章会写成一个自动监听探针。

4. 把探测结果变成台账:字段解读、结果重放与批量提取

4.1 输出字段里藏着设备类型:IP、MAC 与厂商信息的读法

netdiscover 的输出不是单纯的 IP 列表,每一行包含三个核心字段:IP 地址、MAC 地址、MAC 地址对应的厂商信息。最后一项是它最值钱的地方——厂商标识直接对应设备类型,大多数品牌设备的前 24 位 MAC 是注册过的 OUI,netdiscover 内置了厂商数据库。我在办公网扫完一轮,看到 Raspberry Pi 的 MAC 段就知道是谁的开发板,看到 TP-Link 的段基本能断定是家用路由器私接,看到树莓派和品牌机的混搭组合还能判断是不是有人在做测试环境。

192.168.1.1 74:da:da:xx:xx:xx TP-LINK TECHNOLOGIES CO.,LTD. 192.168.1.105 b8:27:eb:xx:xx:xx Raspberry Pi Foundation 192.168.1.120 dc:a6:32:xx:xx:xx Espressif Inc.

厂商信息是识别未知设备的第一步,但不能只靠它下结论。DIY 设备可以烧录任意 MAC,开源物联网固件里修改 MAC 是常规操作。看到 ESP32 的 MAC 出现在网段里,不代表那就是一个 ESP32 模组,也可能是一台运行了支持 ESP32 网卡的调试主机。厂商信息作为排查线索很有价值,但最终确认设备类型还得靠端口识别或设备自身特征。

4.2 参数 -L 与 -l:扫描结果落盘和重放的细节

主动模式默认输出只在屏幕显示,进程结束结果就丢了。资产盘点如果没有留档,下次对比"多了哪台设备"就无从谈起。netdiscover 提供了 -L 参数把扫描结果保存到文件,保存格式是 CSV 兼容的纯文本,方便后面用脚本批量处理。

sudo netdiscover -i eth0 -r 192.168.1.0/24 -L /var/log/arp_inventory.log

这个文件里存的是 IP、MAC、厂商三字段加分隔符的数据。原始文件可以直接用 grep 按条件筛选,比如过滤新出现的 MAC 地址;也可以导入 Excel 做台账排序。保存文件时注意权限:netdiscover 以 root 运行,写出的文件默认属主是 root,后续用普通用户脚本读取时需要处理权限或把输出路径放到普通用户可写的目录下。

对应的 -l 参数用于重放扫描结果,用法是你先 -L 保存了一份结果,之后想重新整理或验证当时的网络状态,用 -l 把存下来的文件重新读出来看。文件重放不需要网卡,在没有网络的机器上也能离线分析历史数据,相当于把一次真实扫描做成了可复制的快照。

netdiscover -l /var/log/arp_inventory.log

重放模式下界面和真实扫描一致,但不会发出任何网络包。我一般把 -L 当成标准操作固定进命令,扫描结束立即留档,排障时遇到"上周是什么状态"这种问题,翻日志比重新扫描靠谱得多。

4.3 用 awk/grep 批处理:每天自动生成一份资产变化清单

有了落盘文件就能批处理了。手头没有现成资产列表时,一条 awk 命令就能把 netdiscover 的输出转成干净的 IP-MAC 映射表;配合 grep 过滤设备类型,几十行的脚本就能完成"今天多了哪台设备、少了哪台设备"的差异比对。

awk -F' +' ' /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ { gsub(/^ +| +$/, "", $1); mac = $2; ip = $1; vendor = $3; printf "%s\t%s\t%s\n", ip, mac, vendor }' /var/log/arp_inventory.log

-F' +' 把连续空格作为分隔符,这种分隔方式对 netdiscover 的输出格式兼容性最好。gsub 去掉 IP 首尾的空格,然后按 IP、MAC、厂商三列重新排版输出。如果只需要 IP 列表喂给其他脚本,把 printf 改成只输出 $1 即可。

在实际项目里,我把这个 awk 脚本和定时任务配合,每天早上跑一轮主动扫描生成当天资产清单,再与前一天的清单做 diff,差异部分自动发到监控群。这样工作日第一天打开工作群就能看到夜间接入过哪些设备。这就是资源类项目最有吸引力的落地场景之一:数据从单个工具里流出来,进入自己的开源项目管理流程。

5. 避坑指南:网卡、混杂模式、ARP 代理与扫描时序

5.1 网卡与系统层面的坑

现象一:被动模式挂在无线网卡上,跑了十分钟结果一个包都抓不到。

原因一:无线路由器开启了 AP 隔离功能。开启了客户端隔离后,无线客户端之间的单播帧会被交换芯片直接丢弃,网卡虽然处于混杂模式也收不到别人之间的 ARP 流量。更常见的是 USB 无线网卡本身就不支持完整的混杂模式抓包,驱动把混杂模式忽略掉,只把属于本接口的帧递交上来。

解决一:遇到这种场景优先换有线网卡;必须在无线环境用时,先去路由器管理后台确认 AP 隔离关没关。检查网卡是否真正进入混杂模式,用 ip link show eth0 | grep PROMISC 确认而不是只看 netdiscover 是否启动。

现象二:在虚拟机里运行 netdiscover,结果只扫出了宿主机和自己,其他同一虚拟网段的机器全部消失。

原因二:虚拟机网卡接在 NAT 或 Host-Only 虚拟交换机上,虽然 IP 都在 192.168.x.0/24,但二层网络隔离。ARP 广播只在这个虚拟网络内传播,跨不到物理局域网。桥接模式才让虚拟网卡直接挂在物理网络上。

解决二:把虚拟机网卡改为桥接模式,之后在虚拟机内重新执行扫描。另外注意 VMware 的默认桥接网卡不绑定具体物理网卡,多网卡宿主机需要在虚拟网络编辑器里指定桥接到哪块真实网卡。

现象三:非 root 执行报 socket 权限错误,折腾半天不知道哪里不对。

原因三:netdiscover 需要构造原始 ARP socket,它没有像某些工具那样在安装时设置 SUID 位,所以必须以 root 运行。

解决三:统一用 sudo 执行;长期探针部署建议用 systemd service 指定 User=root 并配合最小化权限方案,而不是留一个 sudo 长期授权在脚本里。

5.2 网络行为层面的坑

现象一:主动扫描结果显示网关在线,但所有内网主机只有一台有响应,其他 IP 全部超时。

原因一一:部分交换机或路由器启用了 ARP 代理(proxy ARP)。L3 交换机配置了 ip proxy-arp 后,会代其他网段的主机应答 ARP 请求,导致你发出一个请求,网关直接替所有目标回包。结果就是扫描结果中"每台 IP 都有响应",但响应者全是网关的 MAC,而真实主机可能根本就在另一个网段。

解决一:发现大量 IP 对应同一 MAC 的情况先想代理 ARP。用 arp-scan 的 --localnet 模式交叉验证,或者抓包确认 ARP reply 的源 MAC 是否等于目标 IP 的真实 MAC。排查时重点关注响应是否真实、设备是不是在二层内。

现象二:被动模式抓到的设备总数比主动模式少很多,部分 IP 在主动扫描里有记录,被动模式里就是看不到。

原因二:ARP 缓存机制在起作用。局域网设备通信过一次后,IP-MAC 映射被双方缓存在系统 ARP 表里,短时间内不会再重复发 ARP 请求。被动监听只能捕获"缓存有效期之外"新产生的 ARP 流量,缓存没过期的设备之间根本不产生 ARP。主动扫描则无视缓存,逐个询问,所以能全量发现。

解决二:两组结果用途不同,不必追求一致。资产盘点走主动扫描,通信关系分析走被动模式。如果想尽快观察到更多被动流量,向网段里多播几个 ping 触发设备重新进行地址解析即可。

现象三:扫大网段时大量超时,且网卡 CPU 占用飙升。

原因三:netdiscover 是一个串行发包程序,-t 参数控制发包间隔,发完所有请求后有一个固定等待时间。-r 指定 /16 网段时,发包数从 256 个跳到 65536 个,即便 -t 100ms,单轮耗时直接从秒级变成小时级。这个过程中网卡中断频率变高,驱动和系统协议栈扛不住。

解决三:大网段分段扫描,/16 拆成四个 /18 分批跑;调 -s 参数给网卡留出缓冲时间;或者直接结合拓扑确认实际二层范围,不要盲目扫整个大网段。扫完一段保存一段日志,然后换下一段,这样中途出问题也方便断点续扫。

现象四:扫描结果里出现了不在局域网内的私网 IP,并且只有 MAC 没有厂商信息。

原因四:某些开源路由固件和虚拟化平台默认启用 ARP 泛洪或 MAC 欺骗防护,netdiscover 的广播包可能被它当作异常流量镜像篡改,把伪造的 ARP 回应发回来。这类响应没有真实厂商信息,通常是软件伪造的结果。

解决四:这种结果直接过掉,不要把它当成有效资产。生产网络建议在交换机上做端口安全配置而不是仅靠 ARP 扫描做资产发现,netdiscover 本身只是辅助手段。

6. 进阶:搭一个长期 ARP 监听探针,自动发现新接入的设备

把被动监听做成常驻探针,新设备接入局域网时即使没人跑扫描,也能留下记录。核心思路是:netdiscover 被动模式写日志,后台脚本按分钟抽取新 MAC 并比对历史台账,出现增量就输出一条带时间戳的新设备记录。下面是探针脚本的核心部分。

#!/bin/bash LOG_DIR="/var/log/arp_probe" mkdir -p "$LOG_DIR" # 启动被动监听,结果持续写入日志文件 sudo netdiscover -p -i eth0 -L "$LOG_DIR/arp_raw.log" & # 用于去重的历史清单文件 KNOWN_MACS="$LOG_DIR/known_macs.txt" touch "$KNOWN_MACS" # 每分钟从原始日志里抽取新出现的 MAC 并报警 while true; do CURRENT_MACS=$(grep -oE '([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}' "$LOG_DIR/arp_raw.log" | tr '[A-Z]' '[a-z]' | sort -u) while read -r mac; do if [ -n "$mac" ] && ! grep -q "$mac" "$KNOWN_MACS"; then echo "$(date '+%Y-%m-%d %H:%M:%S') new_device $mac" >> "$LOG_DIR/new_devices.log" echo "$mac" >> "$KNOWN_MACS" fi done <<< "$CURRENT_MACS" sleep 60 done

脚本先把被动监听进程挂到后台,再周期性抽取日志里的 MAC 去重比对。中括号里的 tr 处理大小写差异,避免 MAC 地址格式不一致导致漏判;KNOWN_MACS 文件就是历史台账,新发现追加到台账并写入 new_devices.log。用 systemd timer 或 crontab 启动这个脚本即可。

验证探针是否生效有一个直接的办法:找一台手机断开 Wi-Fi 再重新连接,触发一次新的 ARP 交互,然后检查 new_devices.log 里是否新增了手机 MAC 和设备型号信息。我自己的验证习惯是:把探针脚本跑起来后,用 ip neigh show 查看本机 ARP 缓存是否有对应条目,再用一次主动扫描交叉确认。那次我在办公室搭完探针,第二天早上日志里看到半夜新增了一个未知 MAC,顺着厂商信息找到是一台新接入的测试开发板,省去了逐一排查的功夫。从那以后我每次部署网络资产监控都先把 ARP 探针挂上,再谈上层应用。希望帮到你。

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

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

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

立即咨询