用 `nmap -sn 192.168.1.0/24` 这条命令,何获三秒钟就能拿到整个网段的取某全部存活 IP 列表。这是网段我在排查办公室网络时最常用的手段——比挨个 ping 快得多,也比翻 DHCP 租约表靠谱。何获前提是取某全部你得有权限扫这个网段,别拿去扫别人的网段。
但很多人只知道 `-sn`,何获不知道它背后干了什么。取某全部nmap 会先发 ARP 请求(局域网内),网段拿到 MAC 地址就标记为存活;跨网段时改用 ICMP echo 和 TCP SYN 到 80/443 端口。何获所以防火墙一挡 ICMP,取某全部结果就不准了。网段我遇到过一台打印机,何获ICMP 被关了但 9100 端口开着,取某全部`-sn` 扫不出来,网段加 `-PS9100` 才现形。
ARP 扫描:局域网里最快的方式
如果目标就在同一个二层网络里,`arp-scan` 比 nmap 更直接。`arp-scan --localnet` 会向广播地址发 ARP 请求,所有活着的设备都得回应——ARP 是链路层协议,防火墙基本管不着。输出里连网卡厂商都给你标好,看到 `Hon Hai` 就知道是富士康代工的设备,大概率是某台笔记本或手机。
Windows 上没这工具,但 `arp -a` 能看到本机 ARP 缓存里已有的条目。缺点是缓存不全,没通信过的设备不出现。想主动刷新,可以配合 `for /L %i in (1,1,254) do @ping -n 1 -w 10 192.168.1.%i >nul` 先把整个网段 ping 一遍,再 `arp -a`。这招土,但管用。
ping 扫段:最笨也最普适
Linux 下 `for i in $(seq 1 254); do ping -c 1 -W 1 192.168.1.$i | grep "64 bytes" & done; wait` 一行搞定。`&` 让 254 个 ping 并发跑,`wait` 等全部结束。不并发的话,254 秒就没了。`-W 1` 把超时压到 1 秒,不然默认等太久。
有个坑:有些系统 ping 回显不是 "64 bytes",macOS 是 "56 bytes",得按自己系统调 grep 模式。更稳的做法是看退出码:`ping -c 1 -W 1 $ip > /dev/null && echo $ip`。退出码为 0 就是通了。
用 Python 脚本拿更多信息
想同时拿到主机名和开放端口,写个十几行脚本更灵活。用 `subprocess` 调 ping 判断存活,再用 `socket.gethostbyaddr()` 反查 DNS,最后 `socket.connect_ex()` 探几个常见端口。我写过一个版本,扫描完直接输出成 CSV,IP、主机名、MAC、开放端口四列。比 nmap 的 XML 输出好读。
但 Python 的 `socket.gethostbyaddr()` 在纯内网环境经常超时,因为反向 DNS 查不到。加个 `socket.setdefaulttimeout(0.5)` 控制住,不然一个 IP 卡五秒,扫完整个网段得半小时。
别忽略 IPv6
现在很多设备默认开了 IPv6,`fe80::` 开头的链路本地地址用 `ping6 ff02::1%eth0` 能一次性发现同一链路上的所有节点。`ff02::1` 是全部节点组播地址,所有 IPv6 设备都得响应。这比 IPv4 的广播扫描干净——不会吵醒不相关的主机。不过响应里只有链路本地地址,要拿全局地址还得再查邻居缓存 `ip -6 neigh`。
实际工作中,我通常先用 `arp-scan` 快速摸底,再用 nmap 做端口确认,最后 Python 脚本整理成表。三步下来,一个 /24 网段的完整画像就出来了。工具选哪个不重要,清楚每种方法的边界条件才关键——ICMP 被挡、ARP 跨不了路由、组播只在本地链路有效,这些限制决定了你什么时候该换手段。