Ako1O/sec-network-device-scanner
GitHub: Ako1O/sec-network-device-scanner
一款本地网络设备扫描工具,通过 ARP 扫描和 MAC 地址厂商查询来发现、记录并标记网络中的新设备或未知设备。
Stars: 1 | Forks: 0
# sec-network-device-scanner
一款命令行工具,可以扫描你的本地网络,列出它发现的每一台设备,并根据设备的 MAC 地址告诉你每个设备可能的制造商。它会保留一份关于此前发现过设备的小型历史记录,因此它可以标记出任何新设备或任何你未明确允许的设备。
其核心理念很简单:大多数人(以及大多数小型网络)都没有简单的方法来回答“当前到底有哪些设备连接到了我的网络?”此工具只需一条命令即可回答这个问题,并在答案发生变化时为你提供警报。
它还附带了一个独立的 HTML 报告查看器,因此无需安装任何软件即可在浏览器中查看扫描结果。

## 功能说明
- 扫描本地子网,并列出它能探测到的每一台设备,显示其 IP 和 MAC 地址
- 根据设备的 MAC 地址查找其制造商(Apple、TP-Link、Raspberry Pi Foundation 等)
- 在一个小型本地 JSON 数据库中记录跨多次扫描的设备信息,从而了解哪些是新设备
- 将新设备或不在你允许列表中的设备进行标记
- 两种扫描方式:快速的 ARP 扫描(通过 scapy 实现)以及无需额外驱动的 Windows 友好型备用方案
- `watch` 模式,按设定间隔重新扫描,并在发现异常情况时立即停止
- 提供 JSON 输出,可用于编写脚本、记录日志或输入到其他工具中
- 专为自动化设计的退出代码(见下文)
- 静态 HTML 报告查看器,无需服务器或安装即可直观浏览扫描结果
## 报告查看器
[`ui/dashboard.html`](ui/dashboard.html) 是一个独立的、自包含的 HTML 文件。双击它(或在任何浏览器中打开),它会自动加载预设的示例数据,让你立即了解报告的样貌。
要查看真实的扫描结果,请使用 `--out report.json` 运行该工具,然后将该文件拖放到页面上,或通过文件选择器打开。一切操作都在浏览器中完成:文件在本地读取,不会向任何地方发送数据。

## 工作原理
1. 检测你当前活动的网络接口和本地子网(例如 `192.168.1.0/24`)
2. 扫描该子网以查找活动主机,并解析每台主机的 IP → MAC 地址
3. 查找 MAC 前缀(OUI)以识别制造商
4. 将结果与你的允许列表以及之前扫描中发现的设备进行比对
5. 在终端中打印表格,并可选择将结果写入 JSON 文件
6. 根据是否发现任何异常情况返回相应的退出代码
## 安装说明
### 环境要求
- Python 3.11 或更高版本
- Windows、macOS 或 Linux。在 Windows 上进行快速的 ARP 扫描需要安装 [Npcap](https://npcap.com/)(在 Linux/macOS 上则需要 libpcap);如果未安装,Windows 会自动回退到内置的 ARP 探测方式。
### 安装步骤
```
git clone https://github.com//sec-network-device-scanner.git
cd sec-network-device-scanner
python -m venv .venv
# Linux/macOS
source .venv/bin/activate
# Windows (PowerShell)
.venv\Scripts\Activate.ps1
pip install -e .
```
这将安装 `sec-network-device-scanner` 命令,同时也支持使用 `python -m sec_network_device_scanner` 来运行。
## 用法
### 基础扫描
```
sec-network-device-scanner scan
```
### 将结果保存到文件
```
sec-network-device-scanner scan --out report.json
```
打开 `ui/dashboard.html` 并加载 `report.json` 即可浏览结果。
### 仅标记未明确允许的设备
```
sec-network-device-scanner scan --allow allowlist.json --strict
```
### 持续监控并在首次触发警报时停止
```
sec-network-device-scanner watch --interval 60 --strict --allow allowlist.json
```
### 机器可读输出
```
sec-network-device-scanner scan --json
```
使用 `--json` 时,人类可读的表格会发送到 stderr,而单个 JSON 对象会打印到 stdout,因此可以安全地通过管道进行传输。
### 允许列表(allowlist.json)示例
```
{
"devices": [
{ "mac": "AA:BB:CC:11:22:33", "name": "My Laptop" },
{ "mac": "44:55:66:77:88:99", "name": "Router" }
]
}
```
## 输出示例
### 终端
```
Found: 6 devices | New: 1 | Unknown: 1
Role IP MAC Manufacturer Status Name
Gateway 192.168.1.1 AA:11:22:33:44:00 TP-Link Known Home Router
Client 192.168.1.10 3C:22:FB:10:20:30 Apple Allowed Alex's MacBook
Client 192.168.1.14 B8:27:EB:AA:BB:CC Raspberry Pi Foundation Known Home Server
Client 192.168.1.22 00:1A:11:22:33:44 Google Known Living Room Speaker
Client 192.168.1.37 F4:5E:AB:10:9B:2C Samsung New
Client 192.168.1.63 12:34:56:78:9A:BC (unknown) Unknown
```
### JSON (`--json` 或 `--out`)
```
{
"timestamp_utc": "2026-07-18T09:14:02+00:00",
"network": "192.168.1.0/24",
"gateway_ip": "192.168.1.1",
"counts": { "found": 6, "new": 1, "unknown": 1 },
"devices": [
{ "role": "Gateway", "ip": "192.168.1.1", "mac": "AA:11:22:33:44:00", "manufacturer": "TP-Link", "status": "Known", "name": "Home Router" }
],
"mode": { "strict": false, "learn": false, "no_db": false, "method": "auto", "max_workers": 100 }
}
```
### 退出代码
旨在用于脚本、cron 任务或 CI 中:
| 代码 | 含意 |
| ---- | -------------------------------------------------------- |
| 0 | 未发现任何异常情况 |
| 1 | 发现新设备或未知设备(取决于所使用的模式) |
| 2 | 运行时错误(权限不足、未找到网络接口等) |
## 项目结构
```
sec-network-device-scanner/
├─ src/sec_network_device_scanner/
│ ├─ __init__.py
│ ├─ __main__.py # enables `python -m sec_network_device_scanner`
│ ├─ cli.py # argument parsing, scan/watch commands, output formatting
│ ├─ scanner.py # network detection and the actual ARP scanning
│ ├─ oui.py # MAC address to manufacturer lookup
│ └─ storage.py # the local "devices seen before" database
├─ ui/
│ └─ dashboard.html # standalone report viewer, opens directly in a browser
├─ docs/
│ └─ screenshots/ # screenshots used in this file
├─ tests/
├─ pyproject.toml
├─ allowlist.example.json
└─ README.md
```
## 开发指南
```
pip install -e .
pip install -r requirements-dev.txt
pytest
ruff check .
```
## 故障排除
**扫描到了错误的网络。** 如果你安装了 VMware、VirtualBox、Hyper-V 或 VPN 客户端,你的电脑就会在真实的 Wi-Fi 或以太网连接之外多出一些虚拟网络适配器,而自动检测偶尔会选中其中一个。运行带有 `--show-nets` 参数的命令,可以查看工具找到的每个候选网络及其最终选中的网络:
```
sec-network-device-scanner scan --show-nets
```
VMware 的默认虚拟适配器很容易辨认——它们通常显示为 `192.168.230.0/24` 和 `192.168.232.0/24`。你真实的网络就是那个与 `ipconfig`(Windows)或 `ifconfig`/`ip addr`(macOS/Linux)中 Wi-Fi 或以太网适配器旁边显示的 IP 地址相匹配的网络。确认无误后,直接强制指定该网络即可:
```
sec-network-device-scanner scan --cidr 192.168.1.0/24
```
**只能扫描到一台设备(网关)。** 这通常不是 Bug——这意味着该网络开启了*客户端隔离*(也称为 AP 隔离),这会阻止连接的设备互相发现,在办公网络、访客网络和公共 Wi-Fi 中很常见。你自己的家用路由器几乎总是默认关闭此功能,因此你应该能在家里看到其他设备。如果你在使用家庭网络时依然只能扫描到网关,请尝试以管理员身份运行终端,或者确保已安装 [Npcap](https://npcap.com/),以便该工具可以使用更快的基于 scapy 的扫描方式,而不是备用方案。
**Scapy 打印出关于找不到接口的 traceback。** 这是因为 scapy 未能找到真实的捕获设备(通常是因为未安装 Npcap),工具会自动回退到 Windows 的 ARP 扫描方式——那个看起来吓人的 traceback 仅供参考,并非致命错误,扫描仍会正常完成。
## 安全说明与局限性
本工具适用于你自己拥有的或已获得扫描许可的网络。它仅在网络层(ARP)进行设备发现——它不会对设备进行端口扫描,也不会尝试识别设备上运行的服务。
以下几点需要注意:
- 扫描结果取决于你的计算机在网络上实际能探测到的内容。VLAN、客户端隔离和防火墙规则都可能会在扫描中隐藏设备。
- 制造商检测基于 MAC 的 OUI 前缀,属于尽力而为的匹配。某些制造商不在数据库中,而且许多现代设备(尤其是手机)会随机化其 MAC 地址,这将显示为“Local / randomized MAC”而不是真实的供应商。
- 如果设备处于休眠状态、位于不同的子网或隐藏在 NAT 之后,则可能会被漏扫。
## 许可证
MIT — 详见 [LICENSE](LICENSE)。
标签:Homebrew安装, MAC地址识别, 云存储安全, 多模态安全, 插件系统, 网络扫描, 网络调试, 自动化, 设备发现, 逆向工具