LazyGatto/mikrotik-psk-knock
GitHub: LazyGatto/mikrotik-psk-knock
面向 MikroTik 路由器的认证端口敲击工具,通过 PSK 时间令牌临时开放服务端口,避免端口长期暴露于互联网。
Stars: 0 | Forks: 0
mkpk — MikroTik PSK Knock
在 MikroTik 上通过 authenticated port-knock 临时开放服务。
端口不会一直暴露在互联网上——只有在带有密钥的“敲击”成功后,
才会为特定地址短暂开放。
Releases ·
Roadmap ·
Man pages ·
English
## 这是什么
全天候从互联网开放的 `dst-nat` 端口转发是一个持续存在的攻击目标。**mkpk**
会将服务保持关闭,并对其进行精准开放:客户端发送分阶段的 UDP“敲击”和
短暂的 PSK token,路由器对其进行验证,并将**该特定的**源地址添加到
带有超时设置的 allowed-list 中。在其余时间里,端口均处于关闭状态,路由器上既没有
永久开口,也没有暴露外部服务——这一切完全依赖 RouterOS 的原生功能实现。
该项目不仅仅是协议,更是围绕它构建的一套完整工具集:
- **运行时客户端** `mkpk` —— 发起“敲击”并检查可用性 (CLI)。
- **管理端** `mkpk-provision` —— 配置、RouterOS 脚本渲染、通过 SSH 部署、
向客户端分发。支持作为 **CLI**、**本地 web UI** (`serve`) 以及 **桌面应用**
(`mkpk-provision-desktop`,基于 Wails 的原生窗口) —— 它们均构建于同一核心之上。
- **macOS 客户端** (`client-macos/`) —— 面向受邀者的原生**菜单栏应用**:导入
`.mkpk`,执行敲击/检查,显示开放访问的倒计时,并支持“保持开启”(在到期前
自动重新敲击)。使用与 CLI 相同的加密运行时
(使用 Swift 重写,并与 Go 的 golden 测试向量进行了比对验证)。
CLI 和 web UI(`serve`,在浏览器中打开)可在**任何操作系统**上运行;原生桌面应用
只是同一 UI 的便捷封装,并且仅针对 macOS 进行构建。加密运行时
完全在客户端执行;SSH 仅作为部署通道。
## 截图
**Provision —— 桌面应用**(服务概览与编辑器):

**客户端** —— macOS 菜单栏应用(导入邀请、敲击、“保持开启”):
## 功能特性
- **基于 PSK-time-token 的 Port-knock** —— 分阶段的 UDP 作为轻量级过滤器 + 绑定
时间的 `sha512` token(bucket),`token-hit → poller → allowed` 的 poller 模型有效缩短了重放窗口。
- **多路由器、用户 × 服务** —— 一份配置适配多台路由器;权限矩阵;每对
(用户,路由器)配备独立的 PSK;基于服务 (per-service) 的 token。
- **向客户端分发** —— 面向用户的精简 invite-blob(仅包含其路由器地址、PSK、服务),
无需共享管理配置。
- **三种前端,同一核心** —— CLI(可编写脚本,适用于 Ansible)、本地 web UI(loopback +
按会话生成的 token)以及桌面封装。
- **通知** —— 每次成功敲击都会发送 webhook / Telegram / email 通知,并支持优雅降级。
- **SSH Provisioning** —— 通过 SSH 安装/更新/移除配置层,幂等执行(基于 config-hash 检测),
支持 dry-run。
- **默认安全** —— 包含所有机密信息的配置文件会以 0600 权限原子写入,且不会离开
本机;web 仅限 loopback 访问;invite 仅携带路由器的公共地址。
## 工作原理
```
client
-> UDP knock stage 1
-> UDP knock stage 2
-> UDP token stage с короткоживущим PSK-токеном
MikroTik
-> добавляет src-address в token-hit address-list
-> poller выбирает допустимый hit и помечает bucket/token как used
-> добавляет этот src-address в allowed address-list с таймаутом
-> шлёт уведомление владельцу
-> dst-nat начинает работать только для этого src-address
```
## 路由器要求
- RouterOS 7.x(已在 7.23.2 上测试)。
- **精准的时间(需启用 NTP)。** Token 绑定到 30 秒的 time-bucket,路由器仅接受
当前 + 上一个 bucket。如果路由器时间偏差超过约半个 bucket,token
将不再匹配,导致**敲击静默失败**(在 firewall 中可见:stage1/stage2 匹配,但
token 规则 —— 0 个数据包)。启用方式:`/system ntp client set enabled=yes` + 添加服务器。
Provision 应用(web/桌面)在轮询路由器时会检查时间和 NTP 状态,如果敲击
无法正常工作,将会显示警告。
## 安装说明
预编译的二进制文件位于 [Releases](https://github.com/LazyGatto/mikrotik-psk-knock/releases) 标签页
(由 CI 在 tag 上构建)。每个 CLI 都打包在对应平台的 `.zip` 文件中 —— 内部包含具有
常规命名的二进制文件,并保留了可执行权限位(无需 `chmod +x`)。
对于 **macOS**,还额外提供了两个原生应用 —— **DMG**(拖拽至应用程序文件夹即可安装):
`mkpk-provision-desktop`(管理端)和 `mkpk-client`(客户端接收方,菜单栏应用)。
从源码构建(`client/` 目录):
```
make build # CLI: bin/mkpk и bin/mkpk-provision (версия из git-тега)
make desktop # десктоп-админка .app (macOS; нужны wails CLI + Xcode CLT)
make install # бинари + man-страницы под PREFIX (по умолчанию /usr/local)
make test # go test ./...
```
macOS 客户端是独立的 SwiftPM 项目:`cd client-macos && script/build_app.sh`
(使用 `script/make_dmg.sh` 生成 DMG)。详情请参阅 [client-macos/AGENTS.md](client-macos/AGENTS.md)。
## CLI 与自动化
所有三种前端都是 `internal/admin` 核心的轻量级封装,并且 **CLI 是自给自足的**:web 和
桌面应用的功能均未超出它。典型的无头 (headless) 流程如下:
```
mkpk-provision profile init --out mkpk.yaml --router-name r1 --router-address r1.example.com
mkpk-provision service add --config mkpk.yaml --name ssh \
--stage1-port 41011 --stage2-port 41012 --token-port 41013 \
--target-type forward --target-port 22 --target-to-address 192.0.2.10 --target-to-port 22
mkpk-provision user add --config mkpk.yaml --name laptop --services ssh
mkpk-provision deploy --config mkpk.yaml # ставит слой по SSH
mkpk-provision export --config mkpk.yaml --user laptop --out laptop.mkpk
mkpk knock --invite @laptop.mkpk --service ssh --check # на стороне клиента
```
`deploy` 和 `config validate` 支持 `--json` 以供脚本/Ansible 使用;`check --json` 提供
机器可读的可用性结果。完整参考请查阅 man 页面(`mkpk(1)`,
`mkpk-provision(1)`)或运行 `mkpk-provision help`。
## 状态
可用的纯 ROS 实现方案,包含 CLI、本地 web UI、桌面管理端以及面向受邀者的
**原生 macOS 客户端**,此外还提供 SSH provisioning 和部署进度流式传输;所有功能均已在
真实路由器(RouterOS 7.x)上进行了端到端验证。版本控制遵循 semver,目前处于 1.0 之前阶段;最新版本和二进制文件详见 [Releases](https://github.com/LazyGatto/mikrotik-psk-knock/releases) 标签页。此外还提供
来自 provision 应用的端到端**敲击测试**(执行敲击并通过 SSH 检查路由器的
计数器/日志/端口)以及客户端的“保持开启”功能。后续计划:macOS 构建
的公证 (Developer ID)、ICMP 传输变体。详情请见 [docs/roadmap.md](docs/roadmap.md)。
## ⚠️ 负责任地使用
**mkpk** 是一款网络安全工具。请仅将其用于您自己拥有的系统,或您已获得**明确授权**进行
测试的系统。作者不对任何滥用行为或由此造成的任何损害承担责任。本程序按
“原样”提供,不提供任何形式的保证 —— 参见 [LICENSE](LICENSE)。
## 许可证
[MIT](LICENSE) © Vychegzhanin S. L.
## 文档
- [docs/context.md](docs/context.md) —— 汇总上下文与技术说明。
- [docs/design.md](docs/design.md) —— 纯 ROS 解决方案的初步设计。
- [docs/threat-model.md](docs/threat-model.md) —— 威胁模型与局限性。
- [docs/admin-app.md](docs/admin-app.md) —— 管理应用模型、多路由器、分发 (invite-blob)。
- [docs/multi-profile-render.md](docs/multi-profile-render.md) —— 渲染方案与 data-driven poller。
- [docs/profile-format.md](docs/profile-format.md) —— 配置字段参考。
- [docs/open-questions.md](docs/open-questions.md) —— 待定问题与已采纳的决策。
- [docs/roadmap.md](docs/roadmap.md) —— 后续工作计划。
- [docs/man/](docs/man/) —— CLI man 页面。
- [client/README.md](client/README.md) —— CLI、provisioning 与 SSH 部署细节。
标签:EVTX分析, MikroTik, PE 加载器, Port Knocking, 内存分配, 日志审计, 网络访问控制, 网络运维工具, 路由器配置, 防火墙管理