cldsty/port-scanner
GitHub: cldsty/port-scanner
一款基于 Masscan 与 Nmap 的自动化 TCP 端口监控工具,通过定时扫描和变更检测帮助用户持续掌握网络资产的安全暴露面。
Stars: 0 | Forks: 0
# 防护边界开放端口自动化扫描器
这是一个用于监控开放 TCP 端口的应用程序。它会运行 Masscan 并行获取 banner,通过 Nmap 进一步明确服务详情,将结果保存至 SQLite,并在发现新变动或变更时通过 Telegram 发送通知。
该项目包含定时扫描、变更历史、HTTP API 以及本地 Web 仪表盘功能。
## 项目结构
```
cmd/portscanner/main.go CLI-команды и запуск приложения
internal/config/ загрузка и проверка конфигурации
internal/model/ модели находок, событий и запусков
internal/engine/ общий сценарий сканирования
internal/scanner/ запуск Masscan и разбор JSON
internal/banner/ параллельный сбор и анализ баннеров
internal/nmap/ уточнение сервисов через Nmap
internal/storage/ SQLite, история и сравнение результатов
internal/notifier/ уведомления Telegram
internal/web/ дашборд и HTTP API
```
## 在 Windows 上快速测试
### 1. 准备依赖项
需要准备:
- Go 1.25+ 用于编译;
- Masscan 和 Npcap —— 用于端口扫描;
- Nmap —— 用于明确服务及版本信息;
仓库中提供了两种配置文件选项:
- [config.example.json](config.example.json) —— 包含完整内容的示例;
- [config.template.json](config.template.json) —— 用于自定义配置的模板。
完整示例展示了现成的结构,但包含具体的 Windows 路径和地址。
### 2. 创建配置文件
可以将模板复制为 config.json:
```
Copy-Item config.template.json config.json
```
填入您的具体信息:
```
"masscan_path": "PATH_TO_MASSCAN_EXECUTABLE",
"path": "PATH_TO_NMAP_EXECUTABLE",
"targets": ["TARGET_IP_OR_CIDR"]
```
以下是针对 Windows 和个人路由器的配置示例:
```
"masscan_path": "C:\\Tools\\masscan\\bin\\masscan.exe",
"path": "C:\\Program Files (x86)\\Nmap\\nmap.exe",
"targets": ["192.168.1.1"]
```
如有需要,还可以修改以下内容:
- `scan.ports` —— 待扫描的 TCP 端口;
- `scan.rate` —— Masscan 的扫描速率;
- `scan.interval` —— 自动运行的时间间隔;
- `storage.path` —— SQLite 数据库的存储路径;
- `web.listen` —— 仪表盘的监听地址和端口。
### 3. 配置 Telegram 通知(可选)
1. 打开官方机器人 `@BotFather`。
2. 执行 `/newbot`,设置机器人名称并保存获取的 token。
3. 将 token 设置到当前 PowerShell 窗口中:
```
$env:TELEGRAM_BOT_TOKEN="ВАШ_ТОКЕН"
```
4. 在 Telegram 中打开刚刚创建的机器人,并向其发送一条消息。
5. 发送消息后,请求获取更新:
```
$response=Invoke-RestMethod -Uri "https://api.telegram.org/bot$env:TELEGRAM_BOT_TOKEN/getUpdates"; $response.result | ConvertTo-Json -Depth 10
```
随后找到您的 id。您可以通过以下命令单独获取该值:
```
($response.result | Where-Object {$_.message} | Select-Object -Last 1).message.chat.id
```
如果 `result` 为空,请再次向机器人发送任意消息并重试 `getUpdates`。
6. 将找到的值记录到当前窗口的变量中:
```
$env:TELEGRAM_CHAT_ID="ВАШ_ИДЕНТИФИКАТОР"
```
### 4. 验证基础功能
编译项目:
```
go mod download; go build -buildvcs=false -o portscanner.exe ./cmd/portscanner
```
执行扫描:
```
.\portscanner.exe -config config.json scan
```
成功的结果将包含 `COMPLETED` 状态、扫描结果列表以及 `NEW_HOST`/`NEW_PORT` 事件。
### 5. 验证仪表盘和定时任务
启动完整模式:
```
.\portscanner.exe -config config.json run
```
打开:
```
http://127.0.0.1:8080
```
程序将立即执行一次检查,启动仪表盘,并按照 `scan.interval` 设定的间隔继续扫描。
## 程序功能说明
| 标准 | 实现方式 |
|---|---|
| 快速端口扫描 | 使用可配置 `rate` 的 Masscan |
| 并行处理 | `banner_workers` 处理池和 goroutine |
| 服务识别 | 通过 banner 和 Nmap `-sV --version-light` |
| 历史记录 | 使用 SQLite 存储扫描结果、事件和运行记录 |
| 变更检测 | 将当前状态与上一次状态进行对比 |
| 消息通知 | Telegram Bot API |
| 定时执行 | 内置的 `run` 命令调度器 |
| 实时监控 | Web 仪表盘和 JSON API |
| 免代码配置 | 支持 JSON 配置文件和环境变量 |
## 算法流程图

## 处理阶段
### Masscan
程序会构建如下命令:
```
masscan -p --rate --output-format json --output-filename -
```
`rate` 表示每秒发送数据包的最大速率。
### 并行分析 banner
在 Masscan 完成后,应用程序会与扫描发现的端口建立 TCP 连接。`banner_workers` 用于设置可同时处理的端口数量。
例如:
```
"banner_workers": 10
```
系统可识别常见的协议和服务:HTTP/HTTPS、SSH、FTP、SMTP、POP3、IMAP、MySQL、PostgreSQL、Redis、MongoDB、RDP、SMB、VNC、Docker API 以及 Elasticsearch。
### Nmap
如果 `nmap.enabled` 设置为 `true`,Nmap 将仅扫描已被 Masscan 发现的端口:
```
nmap -Pn -sV --version-light -p -oX -
```
- `-Pn` —— 跳过前置的 ping 扫描;
- `-sV` —— 探测服务及其版本;
- `--version-light` —— 使用轻量级的探测集;
- `-oX -` —— 将 XML 结果输出到标准输出。
来自 `nmap.scripts` 的 NSE 脚本用于对结果进行信息补充。在示例配置中,允许使用 `banner`、`http-title`、`http-headers`、`ssl-cert` 和 `ssh-hostkey`。
### SQLite 及状态对比
默认情况下,数据库位于 `data/scanner.db`。它将存储:
- 扫描历史记录;
- 当前开放及此前关闭的端口;
- 服务、产品及版本信息;
- 原始 banner;
- 首次及最后一次发现的时间;
- 状态变更事件。
- 运行失败的状态及错误文本。
支持的事件类型:
| 事件 | 含义 |
|---|---|
| `NEW_HOST` | 首次发现的主机 |
| `NEW_PORT` | 首次发现的开放端口 |
| `REOPENED_PORT` | 之前关闭的端口重新开放 |
| `CLOSED_PORT` | 之前开放的端口停止响应 |
| `SERVICE_CHANGED` | 服务、产品或版本发生变更 |
| `BANNER_CHANGED` | banner 的稳定部分发生变动 |
对于 HTTP 协议,系统会自动忽略诸如 `Date`、cookie、`nonce` 和 `opaque` 等动态值,以防它们在每次运行时触发误报。同时,完整的原始 banner 仍会被完整保存下来。
### 风险等级
采用的风险等级如下:
```
INFO → LOW → MEDIUM → HIGH → CRITICAL
```
风险评估基于端口号和服务类型生成。这主要用于确定监控的优先级,而非确凿的漏洞验证。
参数 `notifications.minimum_severity` 用于设定触发通知的最低风险等级。低于该阈值的事件依然会被记录在数据库中。
## 运行模式
| 命令 | 用途 |
|---|---|
| `scan` | 执行单次扫描并输出 JSON |
| `run` | 启动仪表盘、立即执行扫描并开启定时任务 |
| `serve` | 仅启动仪表盘和 API |
| `findings` | 输出已知的扫描结果 |
| `events` | 输出近期的事件 |
| `history` | 输出运行历史记录 |
| `config-check` | 检查配置文件 |
标准格式:
```
.\portscanner.exe -config config.json <команда>
```
## 仪表盘
监听地址由 `web.listen` 参数设定。默认值为:
```
127.0.0.1:8080
```
仪表盘展示内容:
- 活跃节点数量;
- 开放端口及运行的服务;
- 风险等级;
- 近期事件;
- 运行历史。
页面会通过 API 每 5 秒自动获取最新数据,无需手动刷新。
## HTTP API
| 方法与路径 | 用途 |
|---|---|
| `GET /api/findings?open=true&limit=100` | 获取当前或所有扫描结果 |
| `GET /api/events?limit=100` | 获取近期的事件 |
| `GET /api/scans?limit=100` | 获取运行历史记录 |
| `POST /api/scan` | 异步触发一次扫描任务 |
## 核心配置参数
| 参数 | 用途 |
|---|---|
| `scan.targets` | IP 地址和 CIDR 网段 |
| `scan.ports` | TCP 端口及范围 |
| `scan.rate` | Masscan 每秒发送的最大数据包数 |
| `scan.masscan_path` | Masscan 的执行路径 |
| `scan.masscan_args` | Masscan 的附加参数 |
| `scan.interval` | `run` 模式下两次运行的间隔时间 |
| `scan.banner_workers` | 并发处理 banner 的 worker 数量 |
| `scan.connect_timeout` | TCP 连接超时时间 |
| `scan.read_timeout` | 读取 banner 数据的超时时间 |
| `scan.max_banner_bytes` | banner 的最大字节数 |
| `scan.input_file` | 读取现成的 Masscan JSON 文件代替实际运行 |
| `nmap.enabled` | 启用 Nmap 附加检测 |
| `nmap.path` | Nmap 的执行路径 |
| `nmap.timeout` | Nmap 扫描单个主机的最长时间 |
| `nmap.scripts` | 允许执行的 NSE 脚本 |
| `storage.path` | SQLite 数据库路径 |
| `notifications.minimum_severity` | 触发 Telegram 通知的最低风险阈值 |
| `notifications.telegram.enabled` | 启用 Telegram |
| `web.enabled` | 在 `run` 模式下启用仪表盘 |
| `web.listen` | 仪表盘/API 的监听地址和端口 |
## 限制说明
- Masscan 通常需要以管理员权限运行,并需安装 Npcap。
- 运行环境的计算机必须能够直接或通过 VPN/TUN 访问 Telegram。
标签:CTI, EVTX分析, Go语言, Masscan, Nmap, SOC, 子域名侦测, 插件系统, 数据统计, 日志审计, 程序破解, 端口扫描, 网络安全, 虚拟驱动器, 资产监控, 隐私保护