# network-scanner **Repository Path**: hulimianju/network-scanner ## Basic Information - **Project Name**: network-scanner - **Description**: No description available - **Primary Language**: Unknown - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-16 - **Last Updated**: 2026-01-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # NetScanner - 内网扫描工具 一个功能完整的内网设备发现和网络拓扑分析工具,支持命令行和 Web 两种界面。 ## 功能特性 - **设备发现** - ARP/ICMP 扫描发现内网所有设备 - **设备识别** - MAC 地址厂商查询、端口扫描识别设备类型 - **拓扑分析** - 自动构建网络拓扑图,识别网关和设备层级 - **延时测量** - ICMP/TCP ping,统计延时、抖动、丢包率 - **带宽测试** - 支持 iperf3 和 TCP 吞吐测试 - **可视化** - Web 界面交互式拓扑图,支持层级/力导向视图切换 ## 项目结构 ``` network-scanner/ ├── scanner/ # 核心扫描模块 │ ├── __init__.py # 模块导出 │ ├── models.py # 数据模型定义 │ ├── discovery.py # 设备发现(ARP/ICMP扫描) │ ├── latency.py # 延时测量模块 │ ├── topology.py # 拓扑分析模块 │ └── bandwidth.py # 带宽测试模块 │ ├── cli/ # 命令行界面 │ ├── __init__.py │ └── main.py # CLI 主程序(typer + rich) │ ├── web/ # Web 界面 │ ├── __init__.py │ └── app.py # FastAPI 应用(内嵌前端) │ ├── netscanner_gui.py # GUI 启动器(双击运行) ├── netscanner.spec # PyInstaller 打包配置 ├── Dockerfile # Docker 镜像配置 ├── docker-compose.yml # Docker Compose 配置 ├── requirements.txt # Python 依赖 ├── setup.py # 安装配置 └── README.md # 本文档 ``` ## 环境要求 - Python 3.8+ - macOS / Linux / Windows - root/管理员权限(ARP 扫描需要) ## 安装 ### 1. 克隆项目 ```bash cd network-scanner ``` ### 2. 创建虚拟环境(推荐) ```bash python -m venv venv source venv/bin/activate # Linux/macOS # 或 venv\Scripts\activate # Windows ``` ### 3. 安装依赖 ```bash # 基础安装 pip install -r requirements.txt # 完整安装(包含可选依赖) pip install -e ".[full]" ``` ### 4. 安装为命令行工具 ```bash pip install -e . ``` ## 使用方法 ### 命令行界面 (CLI) #### 查看帮助 ```bash netscanner --help ``` 输出: ``` Usage: netscanner [OPTIONS] COMMAND [ARGS]... 内网扫描工具 - 发现设备、分析拓扑、测量延时和带宽 Commands: scan 扫描内网中的所有设备 topology 显示网络拓扑图 latency 测量到目标的网络延时 bandwidth 测试到目标的网络带宽 web 启动 Web 管理界面 info 显示当前网络信息 ``` #### 查看网络信息 ```bash netscanner info ``` 输出: ``` ┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓ ┃ 项目 ┃ 值 ┃ ┡━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩ │ 本机 IP │ 192.168.1.100 │ │ 默认网关 │ 192.168.1.1 │ │ 网络地址 │ 192.168.1.0/24 │ └────────────┴────────────────────┘ ``` #### 扫描网络设备 ```bash # 扫描当前网络(需要 root 权限) sudo netscanner scan # 扫描指定网段 sudo netscanner scan --network 192.168.1.0/24 # 设置超时时间 sudo netscanner scan --timeout 5 # 输出到 JSON 文件 sudo netscanner scan --output devices.json ``` 输出示例: ``` 本机 IP: 192.168.1.100 网关: 192.168.1.1 扫描网络: 192.168.1.0/24 发现 8 台设备 ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓ ┃ IP 地址 ┃ MAC 地址 ┃ 主机名 ┃ 厂商 ┃ 类型 ┃ 延时 ┃ ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩ │ 192.168.1.1 │ aa:bb:cc:dd:ee:ff │ router │ TP-Link │ router │ 1.2ms │ │ 192.168.1.100 │ 11:22:33:44:55:66 │ my-mac │ Apple │ pc │ 0.1ms │ │ 192.168.1.105 │ 77:88:99:aa:bb:cc │ nas │ Synology │ nas │ 2.3ms │ └───────────────┴───────────────────┴──────────┴───────────┴────────┴───────┘ ``` #### 显示网络拓扑 ```bash # 显示 ASCII 拓扑图 sudo netscanner topology # 输出拓扑数据到 JSON sudo netscanner topology --output topology.json ``` #### 测试延时 ```bash # 测试到指定 IP 的延时 netscanner latency 192.168.1.1 # 指定 ping 次数 netscanner latency 192.168.1.1 --count 20 ``` 输出示例: ``` 延时统计 ┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓ ┃ 指标 ┃ 值 ┃ ┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩ │ 最小延时 │ 0.89 ms │ │ 最大延时 │ 3.45 ms │ │ 平均延时 │ 1.23 ms │ │ 抖动 │ 0.56 ms │ │ 丢包率 │ 0.0% │ │ 网络质量 │ 很快 (千兆局域网) │ └──────────┴──────────────────┘ ``` #### 测试带宽 ```bash # 测试带宽(使用 TCP 方法) netscanner bandwidth 192.168.1.1 # 使用 iperf3(需要目标运行 iperf3 -s) netscanner bandwidth 192.168.1.1 --iperf ``` #### 启动 Web 界面 ```bash # 默认端口 8080 netscanner web # 指定端口 netscanner web --port 3000 # 指定监听地址 netscanner web --host 0.0.0.0 --port 8080 ``` 然后访问 `http://localhost:8080` 查看 Web 界面。 ### Web 界面 Web 界面提供以下功能: 1. **网络信息面板** - 显示本机 IP、网关、网络地址 2. **交互式拓扑图** - 使用 vis.js 渲染,支持缩放、拖拽 3. **视图切换** - 层级视图(树状)/ 力导向视图(网状) 4. **设备列表** - 显示所有设备详细信息 5. **实时测试** - 点击设备可测试延时 ### API 接口 Web 服务提供以下 REST API: | 端点 | 方法 | 说明 | |------|------|------| | `/api/info` | GET | 获取网络信息 | | `/api/scan` | GET | 触发网络扫描 | | `/api/topology` | GET | 获取拓扑数据 | | `/api/latency/{ip}` | GET | 测试指定 IP 延时 | | `/api/bandwidth/{ip}` | GET | 测试指定 IP 带宽 | | `/api/bottlenecks` | GET | 获取瓶颈链路 | | `/ws/monitor` | WebSocket | 实时监控 | ## 核心模块说明 ### scanner/models.py 定义数据模型: ```python # 设备信息 class Device: ip: str # IP 地址 mac: str # MAC 地址 hostname: str # 主机名 vendor: str # 厂商 device_type: DeviceType # 设备类型 open_ports: List[int] # 开放端口 is_gateway: bool # 是否为网关 latency_ms: float # 延时 # 延时统计 class LatencyStats: min_ms: float # 最小延时 max_ms: float # 最大延时 avg_ms: float # 平均延时 jitter_ms: float # 抖动 packet_loss: float # 丢包率 # 网络拓扑 class NetworkGraph: devices: List[Device] # 设备列表 links: List[NetworkLink] # 连接关系 gateway: str # 网关 IP ``` ### scanner/discovery.py 设备发现功能: ```python from scanner import scan_network, get_local_network # 获取网络信息 local_ip, gateway, network = get_local_network() # 扫描网络 devices = scan_network("192.168.1.0/24") for device in devices: print(f"{device.ip} - {device.vendor} - {device.device_type}") ``` ### scanner/latency.py 延时测量功能: ```python from scanner import ping # 测量延时 stats = ping("192.168.1.1", count=10) print(f"平均延时: {stats.avg_ms}ms") print(f"丢包率: {stats.packet_loss * 100}%") ``` ### scanner/topology.py 拓扑分析功能: ```python from scanner import build_topology # 构建拓扑 topology = build_topology() # 获取 JSON 数据(用于前端渲染) data = topology.to_dict() # 生成 ASCII 拓扑图 from scanner.topology import topology_to_ascii print(topology_to_ascii(topology)) ``` ### scanner/bandwidth.py 带宽测试功能: ```python from scanner import measure_bandwidth # 测试带宽 result = measure_bandwidth("192.168.1.1") if result.download_mbps: print(f"下载速度: {result.download_mbps} Mbps") ``` ## 依赖说明 ### 必需依赖 | 包名 | 用途 | |------|------| | scapy | ARP/ICMP 包发送和接收 | | netifaces | 获取网络接口信息 | | networkx | 图结构处理 | | typer | CLI 框架 | | rich | 终端美化输出 | | fastapi | Web API 框架 | | uvicorn | ASGI 服务器 | ### 可选依赖 | 包名 | 用途 | |------|------| | python-nmap | 高级端口扫描 | | mac-vendor-lookup | MAC 厂商查询 | | iperf3 | 精确带宽测试 | ## 注意事项 ### 权限要求 ARP 扫描需要 root/管理员权限: ```bash # Linux/macOS sudo netscanner scan # Windows (以管理员身份运行 CMD/PowerShell) netscanner scan ``` ### 网络安全 - 仅在你有权限的网络中使用此工具 - 不要在生产环境中进行频繁扫描 - 遵守当地法律法规 ### 跨平台差异 | 功能 | Linux | macOS | Windows | |------|-------|-------|---------| | ARP 扫描 | ✅ | ✅ | ✅ (需 Npcap) | | ICMP ping | ✅ | ✅ | ✅ | | traceroute | ✅ | ✅ | ✅ (tracert) | ## 常见问题 ### Q: 扫描不到设备? 1. 确保使用 root/管理员权限运行 2. 检查防火墙设置 3. 确认网络地址正确 ### Q: Web 界面打不开? 1. 检查端口是否被占用 2. 确认防火墙允许该端口 3. 尝试使用 `--host 127.0.0.1` ### Q: MAC 厂商显示为空? 安装可选依赖: ```bash pip install mac-vendor-lookup ``` ### Q: iperf3 测试失败? 目标主机需要运行 iperf3 服务端: ```bash # 在目标主机上运行 iperf3 -s ``` ## 开发指南 ### 项目启动 #### 方式一:开发模式(推荐) ```bash # 1. 进入项目目录 cd network-scanner # 2. 创建并激活虚拟环境 python3 -m venv venv source venv/bin/activate # Linux/macOS # 或 venv\Scripts\activate # Windows # 3. 安装开发依赖 pip install -e ".[full]" # 4. 验证安装 python3 -m cli.main info ``` #### 方式二:直接运行(无需安装) ```bash # 安装依赖 pip install -r requirements.txt # 直接运行模块 python3 -m cli.main info python3 -m cli.main scan python3 -m cli.main web --port 8080 ``` ### 调试指南 #### CLI 调试 ```bash # 使用 Python 调试器 python3 -m pdb -m cli.main scan # 添加详细输出 python3 -m cli.main scan --timeout 5 2>&1 | tee debug.log ``` #### Web 调试 ```bash # 开发模式启动(自动重载) uvicorn web.app:app --reload --host 0.0.0.0 --port 8080 # 查看 API 文档 # 启动后访问: http://localhost:8080/docs (Swagger UI) # 或访问: http://localhost:8080/redoc (ReDoc) ``` #### 模块单独调试 ```python # 在 Python 交互环境中测试 python3 >>> from scanner.discovery import scan_network, get_local_network >>> local_ip, gateway, network = get_local_network() >>> print(f"本机: {local_ip}, 网关: {gateway}, 网络: {network}") >>> from scanner.latency import ping >>> stats = ping("192.168.1.1", count=5) >>> print(f"延时: {stats.avg_ms}ms") >>> from scanner.topology import build_topology, topology_to_ascii >>> topo = build_topology() >>> print(topology_to_ascii(topo)) ``` #### VS Code 调试配置 创建 `.vscode/launch.json`: ```json { "version": "0.2.0", "configurations": [ { "name": "CLI - Scan", "type": "python", "request": "launch", "module": "cli.main", "args": ["scan", "--timeout", "3"], "console": "integratedTerminal", "justMyCode": false }, { "name": "CLI - Web", "type": "python", "request": "launch", "module": "cli.main", "args": ["web", "--port", "8080"], "console": "integratedTerminal" }, { "name": "Web - Uvicorn", "type": "python", "request": "launch", "module": "uvicorn", "args": ["web.app:app", "--reload", "--port", "8080"], "console": "integratedTerminal" } ] } ``` #### PyCharm 调试配置 1. 打开 `Run > Edit Configurations` 2. 添加 Python 配置: - **Script path**: 选择 `cli/main.py` - **Parameters**: `scan --timeout 3` - **Working directory**: 项目根目录 ### 单元测试 ```bash # 安装测试依赖 pip install pytest pytest-asyncio pytest-cov # 运行所有测试 pytest tests/ -v # 运行并生成覆盖率报告 pytest tests/ --cov=scanner --cov-report=html # 运行特定测试 pytest tests/test_discovery.py -v ``` 示例测试文件 `tests/test_discovery.py`: ```python import pytest from scanner.discovery import get_local_network, scan_network from scanner.models import Device def test_get_local_network(): local_ip, gateway, network = get_local_network() assert local_ip is not None assert gateway is not None assert "/" in network # CIDR 格式 def test_scan_network_returns_list(): # 注意:实际扫描需要网络环境 devices = scan_network(timeout=1) assert isinstance(devices, list) ``` --- ## 打包与发布 ### 方式一:pip 安装包 #### 构建分发包 ```bash # 安装构建工具 pip install build twine # 构建 wheel 和 sdist python -m build # 构建产物在 dist/ 目录 ls dist/ # netscanner-1.0.0-py3-none-any.whl # netscanner-1.0.0.tar.gz ``` #### 本地安装测试 ```bash # 从 wheel 安装 pip install dist/netscanner-1.0.0-py3-none-any.whl # 验证安装 netscanner --help ``` #### 发布到 PyPI ```bash # 发布到测试 PyPI twine upload --repository testpypi dist/* # 发布到正式 PyPI twine upload dist/* ``` ### 方式二:可执行文件打包 (PyInstaller) 打包后双击即可启动,自动打开浏览器显示 Web 界面。 #### 安装 PyInstaller ```bash pip install pyinstaller ``` #### 快速打包(推荐) 使用项目提供的 spec 文件一键打包: ```bash pyinstaller netscanner.spec ``` 打包完成后,可执行文件在 `dist/NetScanner`(macOS/Linux)或 `dist/NetScanner.exe`(Windows)。 **运行效果:** - 双击运行后自动打开浏览器 - 显示 Web 管理界面 - 自动提示是否需要 sudo 权限 #### 手动打包命令 ```bash # 基础打包(GUI 模式,自动打开浏览器) pyinstaller --onefile --name NetScanner netscanner_gui.py # 包含所有依赖的完整打包 pyinstaller --onefile \ --name NetScanner \ --add-data "scanner:scanner" \ --add-data "cli:cli" \ --add-data "web:web" \ --hidden-import=scapy.all \ --hidden-import=netifaces \ --hidden-import=uvicorn \ --hidden-import=fastapi \ netscanner_gui.py # 产物在 dist/NetScanner (Linux/macOS) 或 dist/NetScanner.exe (Windows) ``` #### CLI 模式打包(命令行工具) 如果需要命令行版本: ```bash pyinstaller --onefile --name netscanner-cli cli/main.py ``` #### 跨平台打包 ```bash # macOS 打包 pyinstaller netscanner.spec # Windows 打包 (需在 Windows 上执行) pyinstaller netscanner.spec # Linux 打包 pyinstaller netscanner.spec ``` ### 方式三:Docker 容器化 #### Dockerfile ```dockerfile FROM python:3.11-slim WORKDIR /app # 安装系统依赖 RUN apt-get update && apt-get install -y \ libpcap-dev \ && rm -rf /var/lib/apt/lists/* # 复制项目文件 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . RUN pip install -e . # 暴露 Web 端口 EXPOSE 8080 # 默认启动 Web 服务 CMD ["netscanner", "web", "--host", "0.0.0.0", "--port", "8080"] ``` #### 构建和运行 ```bash # 构建镜像 docker build -t netscanner:latest . # 运行 Web 服务 docker run -d -p 8080:8080 --net=host netscanner:latest # 运行 CLI 命令 docker run --rm --net=host netscanner:latest netscanner scan # 以特权模式运行(ARP 扫描需要) docker run --rm --net=host --privileged netscanner:latest netscanner scan ``` #### Docker Compose 创建 `docker-compose.yml`: ```yaml version: '3.8' services: netscanner: build: . ports: - "8080:8080" network_mode: host privileged: true restart: unless-stopped ``` ```bash # 启动 docker-compose up -d # 查看日志 docker-compose logs -f # 停止 docker-compose down ``` ### 发布检查清单 - [ ] 更新 `setup.py` 中的版本号 - [ ] 更新 `scanner/__init__.py` 中的 `__version__` - [ ] 运行所有测试确保通过 - [ ] 更新 CHANGELOG - [ ] 构建并本地测试安装包 - [ ] 创建 Git tag: `git tag v1.0.0` - [ ] 推送 tag: `git push origin v1.0.0` --- ## 开发扩展 ### 添加新的设备类型识别规则 编辑 `scanner/discovery.py`: ```python PORT_DEVICE_MAP = { # 添加新的端口-设备类型映射 1234: DeviceType.IOT, } ``` ### 添加新的 API 端点 编辑 `web/app.py`: ```python @app.get("/api/custom") async def custom_endpoint(): return {"message": "自定义接口"} ``` ### 添加新的 CLI 命令 编辑 `cli/main.py`: ```python @app.command() def custom_command(): """自定义命令""" console.print("Hello!") ``` --- ## 许可证 MIT License