UbhiTS/netryx
GitHub: UbhiTS/netryx
一款零依赖、纯 Python 实现的自托管局域网扫描与设备发现仪表板,支持可视化拓扑、自动化 API 与 AI Agent 集成。
Stars: 1 | Forks: 0
# Netryx — 信号制图
一个功能丰富、基于 Web 的网络扫描与发现工具。它能发现你网络上的所有设备,识别它们的身份,映射其开放端口和服务,并为任何运行 Web 界面的设备提供一个**可点击的 URL**。UI 是一个精致的深色“星座图集”仪表板,包含卡片、表格和交互式拓扑图视图。
该引擎是一个单 Python 文件,拥有**零外部依赖**(仅使用标准库)。它会运行一个小型本地 Web 服务器,并在你的浏览器中提供该仪表板。不会向云端发送任何内容——所有扫描和数据都保留在你的机器上。
它还**支持脚本化和 Agent 就绪**:提供一次性 JSON CLI、用于 AI 助手的 Model Context Protocol (MCP) 服务器、文档化的 HTTP/OpenAPI 接口,以及主动的流氓设备警报。请参阅[自动化与 AI Agent](#automation--ai-agents)。
## 文件
| 文件 | 用途 |
|------|---------|
| `netryx.py` | 扫描引擎 + 本地 Web 服务器 + HTTP/MCP API |
| `ui.html` | 仪表板(由引擎提供 —— **请将其与 `netryx.py` 放在一起**) |
| `netryx_mcp.py` | 用于 AI Agent 的 Stdio MCP 服务器(请与 `netryx.py` 放在一起) |
| `openapi.yaml` | HTTP API 的 OpenAPI 3.0 描述(也会在 `/openapi.json` 提供) |
| `run.bat` | Windows 下的双击启动器 |
| `build.bat` | 构建独立的 `Netryx.exe`(内置捆绑 `ui.html`) |
| `Dockerfile`, `docker-compose.yml`, `.dockerignore` | 将其作为容器运行在 NAS/服务器上 |
| `DESIGN_PHILOSOPHY.md`, `signal_cartography.png/.pdf` | UI 背后的视觉设计语言 |
## 为什么它是“本地 Web 应用”而不是纯浏览器端 JavaScript
完全在浏览器标签页内运行的扫描器在物理上无法探测你的局域网 —— 出于安全考虑,浏览器会沙箱化原始网络访问(无 ICMP ping,无 ARP,无任意 TCP 扫描)。Netryx 采用了标准且强大的设计:由一个微小的本地引擎执行真正的扫描,并为你提供在浏览器中打开的 Web UI。
## 选项 A — 本地运行(最简单,无需安装)
1. 安装 **Python 3.8+** (https://www.python.org/downloads/ — 勾选 *"Add Python to PATH"*)。
2. 双击 **`run.bat`**(或运行 `python netryx.py`)。
3. 你的浏览器将打开 `http://127.0.0.1:8765`;你的子网会被自动检测 —— 按下**扫描网络**。
```
python netryx.py # launch + open browser
python netryx.py --port 9000 # choose a port
python netryx.py --no-browser # don't auto-open the browser
python netryx.py --host 0.0.0.0 # listen on all interfaces (use with care)
python netryx.py --scan 192.168.1.0/24 --json # one-shot scan, no server
```
## 选项 B — 预构建单文件应用(无需 Python)
每个版本都会在[发布页面](../../releases/latest)提供独立的二进制文件(内置 UI **和** MCP 服务器)—— 根据你的操作系统下载对应的版本:
| 平台 | 资产 | 运行方式 |
|---|---|---|
| **Windows** | `Netryx.exe` | 双击(未签名 → SmartScreen *更多信息 → 仍然运行*) |
| **macOS** (Intel 及 Apple Silicon) | `netryx-macos-universal.tar.gz` | `tar -xzf … && xattr -dr com.apple.quarantine netryx && ./netryx` |
| **Linux** (任意发行版) | `Netryx--x86_64.AppImage` | `chmod +x …AppImage && ./…AppImage` |
| **Linux** (Ubuntu/Debian) | `netryx__amd64.deb` | `sudo apt install ./netryx_*_amd64.deb` 然后运行 `netryx` |
| **Linux** (便携版) | `netryx-linux-x86_64.tar.gz` | `tar -xzf … && ./netryx` |
二进制文件未签名。macOS Gatekeeper 需要清除隔离标志(上面的 `xattr` 命令),或者首次启动时右键点击 → **打开**;要想完全无摩擦地启动,你需要 Apple 公证。数据按用户存储
(`%APPDATA%\Netryx`, `~/Library/Application Support/Netryx`,
`~/.local/share/Netryx`);可以通过设置 `NETRYX_DATA` 进行覆盖。
要在 Windows 上自行构建 `.exe`,请在装有 Python 的 Windows 机器上运行 **`build.bat`**
(PyInstaller 无法交叉编译,这就是为什么每个 OS 都在 CI 中各自的 runner 上构建的原因)。
## 选项 C — 在你的 NAS / 服务器上使用 Docker
该应用已准备好进行容器化部署。在此文件夹下运行:
```
mkdir -p netryx-data
sudo chown -R 10001:10001 netryx-data # see "data directory ownership" below
docker compose up -d --build
```
然后在网络上的任意浏览器中打开 **`http://:8765`**。
**必须使用 Host networking。** 处于桥接模式的容器位于自己的虚拟网络上,无法看到你真实的局域网 —— 无法发现设备、没有 ARP、没有 mDNS/SNMP。
提供的 `docker-compose.yml` 设置了 `network_mode: host`,并添加了 `NET_RAW` capability 以便 ICMP ping 正常工作。
**你不需要 `--privileged`。** Netryx 仅使用普通 socket 和
`ping` 命令 —— 它从不重新配置网络或发送原始数据包。`NET_RAW`
是它唯一受益的 capability(用于 ICMP),而且这也是可选的:
如果没有它,发现仍然可以通过 TCP 连接探测进行 —— 你只是会失去 ICMP
ping 以及基于 TTL 的操作系统推测。(不需要 `NET_ADMIN`。)
- 在 **Synology** (Container Manager) 或 **QNAP** (Container Station) 上,导入此
项目并确保容器使用 **host** 网络模式。如果你的 NAS UI
不允许 host 模式,应用仍然会加载,但设备发现将
仅限于容器自身的网络。
- 数据(扫描历史记录、设备名称/备注、下载的厂商数据库、基线及
事件)通过挂载的卷持久化保存在宿主机的 `./netryx-data` 中。该
文件夹必须由 uid **10001**(容器用户)拥有 —— 请参阅前面的归属说明。
- 如果端口 8765 被占用,请使用 `NETRYX_PORT` 环境变量更改端口。
普通 `docker` 的等效命令:
```
docker build -t netryx .
mkdir -p netryx-data && sudo chown -R 10001:10001 netryx-data
docker run -d --name netryx --network host \
--cap-add NET_RAW \
-e NETRYX_PORT=8765 -v "$PWD/netryx-data:/data" \
--restart unless-stopped netryx
```
## 功能
**发现与识别**
- 自动检测你的子网(可编辑 —— 扫描任意 CIDR,例如 `10.0.0.0/24`)
- 并发 ping 扫描**外加 TCP 回退机制**,因此可以找到禁止 ping 的设备
- 从 ARP 表中解析 MAC 地址
- 通过 MAC 查找厂商,并带有一个**一键“下载完整数据库”按钮**,可
获取完整的 IEEE OUI 数据库以获取详尽的厂商名称
- 反向 DNS 主机名
- **mDNS / Bonjour** 发现 —— 显示 Chromecasts、AirPlay、打印机、Apple
设备、Sonos、HomeKit 等,并包含友好名称和服务类型
- **SNMP** (v2c) 查询受管交换机、打印机和接入点,以获取其
系统名称和描述
- **NetBIOS** 和 **SSDP/UPnP** 探测,用于获取 Windows 名称和智能设备型号
- 操作系统推测 (TTL) 和设备类型推测(端口 + 厂商 + mDNS + SNMP)
- 往返延迟
**端口、服务与暴露面**
- 并行 TCP connect 扫描 —— **快速**(约 90 个端口)、**扩展**(1–1024)、
**完全**(1–65535)—— 包含服务名称和 banner grabbing
- **Web URL 检测** —— HTTP/HTTPS 端口变为可点击的链接,可直接打开
设备的 Web UI(80 → `http://ip`,443 → `https://ip`,以及 8080/8443/8123/…)
- **暴露评分** —— 每台设备都会根据
存在风险的开放端口(Telnet、RDP、SMB、VNC、暴露的数据库、未授权的 Docker 等)获得一个风险等级(从无到严重)
**视图与工作流**
- **表格**(默认)、**卡片**,以及带有
多种布局和 Obsidian 风格浮动物理效果的交互式**拓扑图**
- 搜索、筛选(仅 Web / 开放端口 / 新设备 / 已命名)以及排序
- **实时监控**:基于定时器自动重新扫描,带有**新设备检测**和
**桌面通知**(浏览器 Notification API)
- **扫描历史记录 + 变更检测** —— 每次扫描都会保存;可重新加载并进行比较
- **Wake-on-LAN**、每台设备的**自定义名称/备注**、**CSV/JSON 导出**
## 自动化与 AI Agent
以下所有内容均使用纯标准库 —— 无需额外安装。
### 一次性 CLI 扫描(无需服务器)
运行单次扫描并打印结果 —— 非常适合 cron 作业和脚本:
```
python netryx.py --scan 192.168.1.0/24 # table output
python netryx.py --scan 192.168.1.0/24 --json # machine-readable JSON
python netryx.py --scan 192.168.1.0/24 --ports --profile quick --json
python netryx.py --scan "10.0.0.0/24, 10.0.5.10" --no-snmp --no-mdns
```
每台设备都包含一个 `risk` 评估(`none`/`low`/`medium`/`high`/`critical`),这是
从其开放端口推导出来的。如果目标无效,退出代码将为非零。
### 用于 AI Agent 的 MCP 服务器
`netryx_mcp.py` 是一个 [Model Context Protocol](https://modelcontextprotocol.io)
服务器,因此像 Claude 这样的助手可以扫描并分析你的网络。将
你的 MCP 客户端指向它:
```
command: python
args: ["/full/path/to/netryx_mcp.py"]
```
`claude_desktop_config.json` 示例:
```
{
"mcpServers": {
"netryx": {
"command": "python",
"args": ["C:\\path\\to\\netryx_mcp.py"]
}
}
}
```
暴露的工具:`network_info`、`scan_network`、`list_devices`、`get_device`、
`find`、`whats_new`、`exposure_report`、`scan_ports`、`wake_device`、
`name_device`、`scan_history`、`get_baseline`、`set_baseline`、`check_rogues`、
`recent_events`。MCP 服务器共享 Netryx 的数据目录,因此它能看到
你的 Web UI 生成的相同扫描历史。
### 通过 HTTP 进行远程 MCP
Web 服务器也支持在 `POST /mcp` (JSON-RPC 2.0) 上使用 MCP,因此远程 Agent
可以访问运行在你 NAS 上的 Netryx。使用 **API token** 对其进行授权
(在仪表板的 **Settings → API tokens** 下创建,或使用旧版
`NETRYX_TOKEN` 环境变量):
```
curl -X POST http://nas:8765/mcp \
-H "Authorization: Bearer nsk_your_token" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```
有关完整信息,请参阅[安全与访问控制](#security--access-control)。
也接受 `?token=` 查询参数(在请求会被记录的地方请避免使用)。
### OpenAPI
完整的 HTTP API 在 `GET /openapi.json` 和 `GET /openapi.yaml` 中
进行了描述(同时也作为 `openapi.yaml` 提交)。将其加载到 Swagger UI、Postman,或
Agent 的工具层中。
### 主动监控:基线 + 流氓警报
将你当前的网络批准为已知的良好**基线**,之后每次扫描
都会与其进行比对。第一次出现**未经批准的设备**或**未经
批准的开放端口**时,Netryx 会记录一个事件,并(可选)将其推送出去。
- 管理基线:`POST /api/baseline {"action":"set"|"approve"|"clear"}`,
或使用 `set_baseline` MCP 工具。
- 读取最近的事件:`GET /api/events`,或使用 `recent_events` MCP 工具。
- 通过设置环境变量
(如下)将警报发送到 **webhook** (HTTP POST) 和/或 **MQTT**。每个警报只触发一次(去重),
直到你重新批准基线。
将此与 UI 中的**实时监控**(或使用 cron 定时执行 `--scan`)结合使用,以实现带有推送通知的连续流氓设备检测。
### 实时事件与推送
Netryx 会在检测到事件的瞬间将其发出,并通过四种
传输方式进行推送,这些方式均由同一个事件日志提供支持。每个事件的格式如下:
```
{ "id": 42, "time": 1700000000.0, "kind": "rogue_device", "severity": "critical",
"data": { "ip": "192.168.1.55", "name": "...", "open_ports": [23, 445] } }
```
事件类型(及严重性):
| 类型 | 严重性 | 触发条件 |
|------|----------|-----------|
| `rogue_device` | critical | 出现不在已知良好基线中的设备 |
| `new_open_port` | high | 基线设备上打开了未经批准的端口 |
| `exposure_alert` | high | 设备达到 **critical** 风险等级 (Telnet/RDP/SMB/暴露的数据库等) |
| `device_missing` | warning | 基线设备消失(保留) |
| `scan_complete` | info | 扫描完成(包含设备/新设备/新端口计数) |
你可以根据客户端的需要来消费它们:
- **MCP 通知:**调用 `subscribe` 工具(可选 `minverity`
和 `kinds` 筛选器)。然后服务器会为每个匹配的事件推送一个 JSON-RPC 通知
`notifications/netryx/event`;`unsubscribe` 可停止推送。
- **Server-Sent Events:**`GET /api/events/stream` (`text/event-stream`);在
`?since=` 之后重放事件,然后进行实时流式传输。浏览器:`new EventSource('/api/events/stream')`
(会话 cookie)。Agent:添加 `?token=nsk_…` (EventSource 无法发送 header)。
- **Long-poll:**`GET /api/events/poll?since=&timeout=25` 会阻塞,直到存在
更新的事件,并返回 `{events, seq}`;使用新的 `seq` 重新轮询。
- **Webhook / MQTT:**设置 `NETRYX_WEBHOOK` 和/或 `NETRYX_MQTT`(如下)—— 每个
事件也会被发送到那里。
`GET /api/events?limit=N` 会为基于拉取的客户端返回最近的日志。
仪表板的 **Events** 面板会订阅 SSE 流,并
将高/严重警报以实时 toast 提示显示(如果启用,还会有桌面通知)。
### 环境变量
| 变量 | 用途 |
|----------|---------|
| `NETRYX_HOST` | 绑定地址(默认 `127.0.0.1`;Docker 使用 `0.0.0.0`) |
| `NETRYX_PORT` | 端口(默认 `8765`) |
| `NETRYX_NO_BROWSER` | 不要自动打开浏览器 |
| `NETRYX_DATA` | 数据目录(历史记录、名称、厂商数据库、基线、事件、token) |
| `NETRYX_USER` | 管理员用户名(默认 `admin`);初始化首次启动 |
| `NETRYX_PASS` | 初始化/覆盖管理员密码(默认登录密码为 `admin`) |
| `NETRYX_TRUST_LOCALHOST` | `0`(默认)在任何地方都提示验证;`1` 跳过 `127.0.0.1` 的身份验证 |
| `NETRYX_OPEN` | `1` 完全禁用身份验证(仅在受信任的网段使用) |
| `NETRYX_SECURE_COOKIES` | `1` 为会话 cookie 添加 `Secure` 属性(在 HTTPS 代理后设置) |
| `NETRYX_SESSION_DAYS` | 登录会话生命周期(以天为单位,默认为 `30`) |
| `NETRYX_TOKEN` | 旧版静态 bearer token(建议使用 UI 中管理的 token) |
| `NETRYX_WEBHOOK` | 用于 POST 事件的 URL |
| `NETRYX_MQTT` | MQTT broker `host` 或 `host:port` |
| `NETRYX_MQTT_TOPIC` | MQTT topic(默认为 `netryx/events`) |
| `NETRYX_MQTT_USER` / `NETRYX_MQTT_PASS` | MQTT 凭据(可选) |
## 安全与访问控制
Netryx **默认是安全的**。首次启动时,它会创建一个管理员登录
账号 **`admin` / `admin`**,并在**整个**应用中要求提供该凭据 —— 包括仪表板、
每个 `/api/*` endpoint 以及 `/mcp`。请在仪表板的 **Settings** 下立即更改它。
**登录:**
- **人类用户** —— 在自定义样式的**登录页面**上登录(会话 cookie 会让
你保持登录状态;**Sign out** 位于仪表板标题栏中)。在
**Settings → Admin login** 下更改用户名/密码;新凭据将被
哈希处理 (PBKDF2) 并持久化到 `netryx-data/auth.json`,因此它们在
重启后依然有效 —— 并且更改密码不会让你退出登录。你也可以
使用 `NETRYX_PASS`(和 `NETRYX_USER`)来初始化
密码,这也可以作为恢复/覆盖登录的方式。
- **Agent 与脚本** —— 在 **Settings → API tokens** 下创建 **API token**。
每个 token 都有名称,显示其创建时间和最后使用时间,并且
**默认长期有效**(如果需要,可以设置以天为单位的过期时间)。token 值保持**可查看状态**,
因此你稍后可以将其复制回 Agent 的配置中。在
API 和 `/mcp` 上搭配使用 `Authorization: Bearer `。token 存放在
`netryx-data/tokens.json`(已被 gitignore)中 —— 请将其视为机密。
**提示与 localhost。**默认情况下,在任何地方都会提示你进行身份验证,包括在
运行 Netryx 的机器上(`NETRYX_TRUST_LOCALHOST=0`)。对于
无摩擦的本地桌面体验,请设置 `NETRYX_TRUST_LOCALHOST=1` 以跳过对
`127.0.0.1` 的提示,同时仍然要求来自其他设备的验证。
在真正受信任的网段上设置 `NETRYX_OPEN=1` 以**完全开放运行**,这
将完全禁用身份验证(会有一个横幅提醒你它已关闭)。
### 使用 nginx 反向代理实现 HTTPS
Netryx 提供的是纯 HTTP,因此密码和 token 以明文形式传输。在
NAS 或任何不受信任的网段上,请将其置于终止 TLS 的反向代理之后:
```
server {
listen 443 ssl;
server_name netryx.example.lan;
ssl_certificate /etc/nginx/certs/netryx.crt;
ssl_certificate_key /etc/nginx/certs/netryx.key;
location / {
proxy_pass http://127.0.0.1:8765;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Pass the caller's credentials (Bearer token / Basic) through:
proxy_set_header Authorization $http_authorization;
}
# The SSE/long-poll endpoints accept a token in the query string (EventSource
# can't set headers). Don't write those URLs to the access log.
location /api/events/ {
access_log off;
proxy_pass http://127.0.0.1:8765;
proxy_set_header Host $host;
proxy_buffering off; # stream Server-Sent Events without buffering
proxy_read_timeout 1h;
}
}
```
在前端终止 TLS 后,请设置 `NETRYX_SECURE_COOKIES=1`,以便会话
cookie 仅通过 HTTPS 发送。
**注意事项:**nginx 会从 `127.0.0.1` 连接到 Netryx。请将
`NETRYX_TRUST_LOCALHOST` 保持为默认值 (`0`),以便代理请求仍然
需要通过身份验证 —— 将其设置为 `1` 会使每个代理请求看起来像是本地的,从而
跳过身份验证。两种可行的方式:
1. **应用强制验证**(保留应用内的 token 管理):设置 `NETRYX_PASS`
和/或创建 API token,设置 `NETRYX_TRUST_LOCALHOST=0`,并让 nginx
传递 `Authorization`(如上所述)。nginx 只处理 TLS。
2. **代理强制验证**:让 nginx 执行其自带的 `auth_basic`,而让
Netryx 信任 localhost。这更简单,但你会失去针对每个 token 的管理。
无论如何,都不要将 Netryx 直接暴露在互联网上。
## 注意事项与提示
- 以 **Administrator / root 身份运行**,以获得最完整的 ARP 和发现结果。
- 首次使用时,**允许它通过你的防火墙**访问专用网络。
- 本地启动器仅绑定到 `127.0.0.1`。Docker/`--host 0.0.0.0` 模式
会将其暴露给你的整个局域网 —— 这对于 NAS 来说是合适的,但不要将其暴露在
互联网上。如果你确实暴露了 `/mcp`,请设置 `NETRYX_TOKEN`。
- **完全**端口扫描(每台主机 65,535 个端口)非常详尽但速度很慢 —— 最好通过单台设备的 **Scan ports** 按钮在对单台主机执行此操作。
- 下载的厂商数据库会保存在数据文件夹中,并在
下次扫描时自动加载。
## 合乎道德的使用
仅扫描你拥有或被授权测试的网络。
## 持续集成
此仓库提供了一个 GitHub Actions 工作流 (`.github/workflows/build.yml`),它会在每次推送和拉取请求时运行:
- **Docker 镜像** → 构建并推送到 GitHub Container Registry (GHCR) 作为 `ghcr.io//netryx:latest`(以及一个 `:` 标签)。在你的 NAS 上拉取并运行它:
mkdir -p netryx-data && sudo chown -R 10001:10001 netryx-data
docker run -d --name netryx --network host \
--cap-add NET_RAW \
-v "$PWD/netryx-data:/data" --restart unless-stopped \
ghcr.io//netryx:latest
该容器以 uid **10001** 身份运行,因此 `netryx-data` 卷必须可由
该 uid(即上面的 `chown` 命令)写入 —— 否则没有任何内容会被持久化。请参阅
选项 C 下的“数据目录归属权”。
- **独立 Windows .exe** → 在 Windows runner 上使用 PyInstaller 构建,并在
每次运行时作为构建**产物**上传。推送版本标签(例如 `git tag v1.0.0 && git push --tags`)也会在 GitHub **Release** 上发布 `.exe`。
无需任何密钥 —— 该工作流使用内置的 `GITHUB_TOKEN` 向 GHCR 验证身份。在首次成功运行后,如果你希望其他人能够拉取它,请从仓库的 *Packages* 页面将 GHCR package 设为公开。
## 隐私
你的扫描结果仅在本地保存。`.gitignore` 排除了 `netryx_data/`(IP、MAC、主机名、设备名称/备注、扫描历史记录、基线、事件、API token 和管理员登录信息)以及常见的机密文件,因此它们永远不会被提交。
标签:Docker, MCP, Python, Web仪表盘, 云存储安全, 内网资产发现, 安全防御评估, 拓扑可视化, 插件系统, 无后门, 网络扫描, 请求拦截, 逆向工具