edglz/portscout
GitHub: edglz/portscout
Portscout 是一个用 Python 和 Textual 构建的 nmap 图形化终端 UI,提供实时进度、日志和配置管理,让端口扫描更直观易用。
Stars: 1 | Forks: 0
# Portscout
### 一个友好的 [nmap](https://nmap.org/) 图形化终端 UI
指指点点,按下按键,即可扫描 —— 配备实时进度条、实时日志、桌面通知,以及底层清晰的[六边形架构](#architecture)。
[](LICENSE)
[](https://www.python.org/)
[](https://textual.textualize.io/)
[](CONTRIBUTING.md)
[](https://buymeacoffee.com/edggdev)
## 概述
Portscout 将 nmap 的强大功能封装在一个易于操作的终端用户界面中。它适合那些想要使用 nmap 的功能但不想记住其各种命令标志的人,同时也适合喜欢带有实时反馈、键盘驱动的快捷仪表盘的经验丰富的用户。
它也是 Python 中**端口与适配器(六边形)架构**的一个小巧、易读的参考实现 —— 其扫描核心与 nmap、文件系统以及 UI 框架完全解耦。
## 功能
- 使用 [Textual](https://textual.textualize.io/) 构建的**图形化 TUI**;可在任何现代终端中运行。
- **真实的进度条**,由 nmap 自身的实时统计数据(`About XX% done` 计时行)驱动,而非虚假的加载动画。
- 扫描运行时逐行流式传输的**实时日志**。
- 针对扫描开始、完成、错误和缺少依赖项的**通知**。
- **扫描配置** —— 包括 ping sweep、快速、标准(服务/版本探测)、带脚本和 OS 探测的完整 TCP,以及常用 UDP 端口扫描。
- **实时命令预览** —— 在启动之前,查看将要运行的确切 `nmap` 命令,并随您的输入实时更新。
- **结果表格** —— 一目了然地查看主机、端口、状态和检测到的服务。
- **配置** —— 持久化到 TOML 文件中;可在应用内编辑 nmap 路径、默认配置、超时时间和输出目录。
- **可选主题** —— 十余种预定义主题(Nord、Gruvbox、Dracula、Tokyo Night、Catppuccin、Solarized 等),支持实时预览且在不同运行间持久保存。
- **依赖检查工具** —— 检查 nmap 和 libpcap/npcap 是否存在,并在缺失时提供安装指南。
- **清晰的六边形架构** —— 领域核心没有任何第三方导入,并且经过了完全的单元测试。
## 演示

*接受合理使用免责声明,输入目标,观察实时进度、流式日志和结果表格。*
### 更多截图
**实时输入验证和命令预览**

**依赖检查工具** · **设置**
**支持实时预览的可选主题**

## 环境要求
Portscout 是一个前端程序,因此它需要在您的系统上安装 `nmap` 二进制文件及其数据包捕获库:
| 平台 | 安装命令 |
| --- | --- |
| macOS | `brew install nmap`(自带 libpcap) |
| Debian / Ubuntu | `sudo apt install nmap libpcap0.8` |
| Fedora / RHEL | `sudo dnf install nmap libpcap` |
| Arch | `sudo pacman -S nmap libpcap` |
| Windows | 安装 [Nmap](https://nmap.org/download.html) 和 [Npcap](https://npcap.com/) |
另外还需要 **Python 3.11 或更高版本**。
## 安装
从源码安装(预发布阶段推荐):
```
git clone https://github.com/edglz/portscout.git
cd portscout
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .
portscout
```
或者免安装直接运行:
```
pip install -r requirements.txt
python -m portscout
```
## 键盘快捷键
| 按键 | 操作 |
| --- | --- |
| `Enter` | 开始扫描(当焦点在目标/端口输入框时) |
| `s` | 开始扫描(当没有输入框获得焦点时) |
| `x` | 停止正在运行的扫描 |
| `c` | 打开设置 |
| `d` | 显示依赖状态 |
| `Ctrl+L` | 清除日志 |
| `q` | 退出 |
## 配置
设置保存在一个 TOML 文件中(其确切路径会在应用内的设置界面中显示):
- Linux / macOS: `~/.config/portscout/config.toml`
- Windows: `%APPDATA%\portscout\config.toml`
```
default_profile = "standard"
nmap_path = "nmap"
output_dir = "~/scans" # if set, each scan's raw XML is written here
timeout_seconds = 600
theme = "textual-dark"
disclaimer_accepted = true
```
## 架构
Portscout 遵循**六边形(端口与适配器)**模式。业务核心从不导入框架,也不生成子进程;它仅依赖于抽象的*端口*。
具体的*适配器*实现这些端口,并在一个单一的组合根中连接在一起。
```
src/portscout/
├── domain/ Pure core: value objects, entities, port interfaces (no third-party deps)
│ ├── value_objects.py Target, PortSpec, ScanProfile (self-validating)
│ ├── entities.py ScanRequest, Host, Port, Service, ScanResult
│ └── ports.py ScannerPort, ConfigPort, DependencyCheckerPort
├── application/ Use cases orchestrating the domain through the ports
│ └── services.py ScanService, ConfigService, DependencyService
├── infrastructure/ Adapters implementing the ports (the driven side)
│ ├── nmap_adapter.py Runs nmap and parses its XML -> ScannerPort
│ ├── config.py TOML persistence -> ConfigPort
│ └── dependencies.py System dependency detection -> DependencyCheckerPort
├── presentation/ Textual TUI (the driving side)
│ ├── app.py Widgets, worker threads, progress, notifications
│ ├── screens.py Disclaimer / Settings / Dependencies modal screens
│ └── styles.tcss Styling
└── bootstrap.py Composition root: the only place adapters are instantiated
```
**为什么这很重要。** 您只需编写一个新的适配器并修改 `bootstrap.py`,就可以将 nmap 替换为 `masscan`,或将 TOML 替换为数据库 —— `domain/` 或 `application/` 中的任何内容都不需要更改。正是这种解耦使得核心业务逻辑在不接触网络的情况下进行单元测试变得轻而易举。
### 扫描的数据流
1. TUI 收集原始输入(目标、配置、端口),并要求 `ScanService` 构建一个经过验证的 `ScanRequest`。无效的输入会在生成任何进程之前被值对象拒绝。
2. `ScanService` 委托给注入的任何 `ScannerPort` —— 在这里也就是 `NmapAdapter`。
3. `NmapAdapter` 使用参数列表(从不使用 shell 字符串)调用 nmap,通过进度回调将其输出流式传输回来,并将生成的 XML 解析为领域实体。
4. TUI 渲染进度,并在完成后渲染 `ScanResult` 表格。
## 安全提示
- nmap 始终使用参数**列表**进行调用,从不使用 `shell=True`,并且目标首先由 `Target` 值对象进行验证,因此不存在 shell 注入的风险面。
- Portscout 从不在后台静默提升权限。需要特权运行的配置会明确报错并提示您使用提升的权限重新启动。
## 开发
```
pip install -e ".[dev]"
pytest # run the test suite
ruff check . # lint
mypy # type-check
textual run --dev portscout.presentation.app:PortscoutApp # hot-reload dev mode
```
## 许可证
[MIT](LICENSE) © Portscout 贡献者。
## 致谢
- [nmap](https://nmap.org/) —— 本项目为其提供了一个友好的界面。
- [Textual](https://textual.textualize.io/) —— 所使用的 TUI 框架。
**支持实时预览的可选主题**

标签:Nmap, Python, Python安全, 插件系统, 数据统计, 无后门, 端口扫描, 终端UI, 网络工具, 虚拟驱动器, 逆向工具