基于 HTTP 协议的远程 Shell 执行系统,集成 noVNC 远程桌面功能。通过 Go 语言编写的单文件可执行程序,在工控机侧启动 HTTP 服务端接收命令和提供 VNC 远程桌面,在开发机侧启动客户端实现类似 SSH 的交互式体验。
当前版本 v2.4:在 v2.3 基础上增强 VNC 兼容性,支持自动检测并使用系统中已运行的其他 VNC Server。
- 零依赖部署:单文件可执行程序,无需安装运行时
- 双角色一体:同一个程序既可当服务端也可当客户端
- Shell 自动检测:按
pwsh → powershell → cmd优先级检测 Windows Shell - 编码自适应:自动处理 Windows GBK/UTF-8 编码问题
- 命令超时控制:超时后主动 Kill 进程
- CORS 跨域支持:允许浏览器端直接调用 API
- 文件上传/下载:通过 multipart/form-data 实现文件传输
- rsync 双向增量同步:
rsync命令:本地→远程增量同步(上传)rsync-pull命令:远程→本地增量拉取(下载)- 基于 Adler-32 + MD5 双阶段校验的块级 delta 同步
- 传输失败自动回退到全量传输
- RFB 文件传输:支持断点续传(offset 参数)、MD5 校验、目录列表
- 服务端日志:自动记录操作日志到
http_shell_cli_{yyyyMMddHHmmssfff}.log - VNC 远程桌面(Windows 服务端):
- 兼容已有 VNC Server:自动检测 RealVNC/TightVNC/UltraVNC 等(端口 5900-5909, 15900-15909),直接复用
- 内嵌 TightVNC Server,无其他 VNC 时自动释放并运行
- 内嵌 noVNC 1.4.0,浏览器直接访问
- WebSocket 代理桥接,无需额外配置
- 自动检测并递增端口避免冲突
http_shell_cli_vnc/
├── http_shell_cli_vnc.go # 主程序(服务端+客户端+rsync+RFB+VNC)
├── http_shell_cli_windows.go # Windows 平台专用(GBK转码、VT颜色、隐藏窗口)
├── http_shell_cli_unix.go # Unix/Linux/macOS 平台空实现
├── public_fs/
│ ├── public_fs.go # embed 静态文件定义
│ ├── novnc/ # noVNC 1.4.0 前端文件
│ └── tvnc/ # TightVNC Server 二进制
│ ├── tvnserver.exe
│ ├── hookldr.exe
│ ├── screenhooks32.dll
│ ├── screenhooks64.dll
│ └── tvnviewer.exe
├── vnc_proxy/
│ ├── proxy.go # WebSocket VNC 代理
│ └── peer.go # VNC 连接对等体
├── go.mod # Go 模块定义
├── go.sum # Go 依赖校验
├── build.ps1 # PowerShell 打包脚本(带时间戳)
├── build.bat # CMD 打包脚本(带时间戳)
└── README.md # 本文档
# 进入项目目录
cd http_shell_cli_vnc
# 下载依赖
go mod tidy
# 编译当前平台版本
go build -o http_shell_cli_vnc.exe .
# 或使用打包脚本(自动添加时间戳后缀)
.\build.ps1 # PowerShell
.\build.bat # CMD打包脚本会生成带时间戳的可执行文件,例如:http_shell_cli_vnc_20260519_132801.exe
# 交互式选择角色
.\http_shell_cli_vnc.exe
# 或直接指定角色
.\http_shell_cli_vnc.exe -role server -host 0.0.0.0 -port 10022Windows 服务端启动时会自动:
- 检测是否已有 VNC Server 运行(兼容模式)
- 扫描端口 5900-5909 和 15900-15909
- 如果检测到 RealVNC/TightVNC/UltraVNC 等,直接复用,跳过注册表和 tvnserver 启动
- 无其他 VNC 时,进入内嵌模式:
- 检测并递增 RFB 端口(默认 15900)避免冲突
- 释放内嵌的 TightVNC Server 到
.cache/tvnc/ - 写入注册表配置(需要管理员权限)
- 启动 tvnserver 服务
- 启动 noVNC HTTP 服务和 WebSocket 代理
# 交互式模式(类似 SSH)
.\http_shell_cli_vnc.exe -role client -url http://192.168.1.100:10022
# 单次执行模式
.\http_shell_cli_vnc.exe -role client -url http://192.168.1.100:10022 -c "Get-Location"在浏览器中打开:
http://192.168.1.100:10022/vnc/vnc.html
无需密码,直接连接即可看到远程桌面。
执行 Shell 命令。
请求体:
{
"command": "Get-ChildItem",
"timeout": 30,
"work_dir": "C:\\Users"
}响应:
{
"status": "success",
"stdout": "...",
"stderr": "",
"exit_code": 0,
"timeout": false,
"command": "Get-ChildItem"
}上传文件到服务端。
参数:
file(file, 必填):要上传的文件path(string, 可选):服务端保存路径
curl 示例:
curl -X POST http://192.168.1.100:10022/upload \
-F "file=@local.txt" \
-F "path=C:/remote/dir/"从服务端下载文件。
参数:
path(string, 必填):服务端文件路径
curl 示例:
curl -X POST http://192.168.1.100:10022/download \
-F "path=C:/remote/dir/file.txt" \
-o local.txt获取文件块集合。
请求体:
{
"path": "/remote/file.dat",
"seed": 12345
}计算增量数据。
Push 模式(默认):
{
"src_path": "/local/file.dat",
"dst_path": "/remote/file.dat",
"seed": 12345
}Pull 模式:
{
"src_path": "/remote/file.dat",
"dst_path": "/local/file.dat",
"seed": 12345,
"direction": "pull",
"local_bs": { ... }
}应用增量数据重建文件。
请求体:
{
"dst_path": "/remote/file.dat",
"src_path": "/remote/file.dat",
"chunks": [
{"op": 1, "length": 256, "data": "..."},
{"op": 2, "length": 5},
{"op": 0}
]
}列出远程目录内容。
下载文件(支持断点续传)。
请求体:
{
"path": "/remote/file.dat",
"offset": 0
}上传文件(支持断点续传)。
参数:
file(file, 必填)path(string, 必填)offset(string, 可选)
计算文件 MD5 校验值。
noVNC 静态文件服务。访问 /vnc/vnc.html 打开远程桌面页面。
VNC WebSocket 代理端点。noVNC 通过此端点与 TightVNC Server 通信。
检查服务状态。
| 命令 | 说明 |
|---|---|
exit, quit, q |
退出客户端 |
cd <目录> |
设置后续命令的工作目录 |
pwd |
显示当前工作目录 |
clear, cls |
清屏 |
!<命令> |
执行本地命令(不发送到服务端) |
upload <本地路径> [远程路径] |
上传文件 |
download <远程路径> [本地路径] |
下载文件 |
rsync <本地路径> [远程路径] |
rsync 增量同步(本地→远程) |
rsync-pull <远程路径> [本地路径] |
rsync 增量拉取(远程→本地) |
rfb-upload <本地路径> [远程路径] |
RFB 断点续传上传 |
rfb-download <远程路径> [本地路径] |
RFB 断点续传下载 |
rfb-list [目录] |
RFB 列出远程目录 |
help, ? |
显示帮助 |
浏览器(noVNC) <--WebSocket--> /websockify <--TCP--> VNC Server(127.0.0.1:5900+ 或 15900+)
- 服务端启动时,优先检测系统中是否已有 VNC Server(端口 5900-5909, 15900-15909)
- 如果检测到已有 VNC Server,直接进入兼容模式,WebSocket 代理连接到已有服务
- 如果没有检测到,释放内嵌的 TightVNC Server 到
.cache/tvnc/,写入注册表,启动 tvnserver - HTTP 服务提供 noVNC 静态页面(
/vnc/) - WebSocket 代理(
/websockify)桥接浏览器与 VNC Server
| 服务 | 默认端口 | 说明 |
|---|---|---|
| HTTP Shell | 10022 | 主 HTTP 服务端口(可配置) |
| VNC RFB | 15900 | TightVNC Server 端口(自动递增) |
| VNC HTTP | 9091 | noVNC 页面端口(与主服务复用) |
- 仅 Windows 服务端支持 VNC:Linux/macOS 服务端不启动 VNC 相关组件
- 兼容已有 VNC Server:支持 RealVNC、TightVNC、UltraVNC 等,无需管理员权限即可复用
- 内嵌模式需要管理员权限:首次运行内嵌 TightVNC 需要管理员权限写入注册表和安装服务
- 端口冲突自动处理:如果 15900 被占用,自动递增到可用端口
- VNC 服务监控:如果内嵌 tvnserver 进程意外退出,程序会自动退出
块大小 = max(700, ceil(sqrt(文件大小)) 向上取整到 8 的倍数)
| 文件大小 | 块大小 | 块数量 |
|---|---|---|
| 100 KB | 700 B | 147 |
| 1 MB | 1,024 B | 1,024 |
| 10 MB | 2,048 B | 5,120 |
| 100 MB | 3,600 B | 28,445 |
| 1 GB | 8,192 B | 131,072 |
| 阶段 | 校验和 | 长度 | 用途 |
|---|---|---|---|
| 第一阶段 | Adler-32 滚动校验和 | 4 字节 | 快速滚动比较,O(1) 滑动窗口更新 |
| 第二阶段 | MD5 强校验和 | 16 字节 | 强验证,混入随机种子防止哈希碰撞 |
rsync 在以下情况自动回退到全量传输:
- 远程文件不存在
- blockset 获取失败 / delta 计算失败 / apply 失败
- MD5 验证不匹配
- 增量效率 < 20%(且文件 > 1MB)
| 变量名 | 默认值 | 说明 |
|---|---|---|
HTTP_SHELL_PORT |
10022 |
服务端监听端口 |
HTTP_SHELL_HOST |
0.0.0.0 |
服务端监听地址 |
HTTP_SHELL_TIMEOUT |
30 |
默认命令超时秒数 |
- 增强 VNC 兼容性:自动检测并使用系统中已运行的 VNC Server
- 支持 RealVNC、TightVNC、UltraVNC 等常见 VNC 服务端
- 无需管理员权限即可在已有 VNC 环境下运行
- 新增 VNC 远程桌面功能(TightVNC Server + noVNC + WebSocket 代理)
- 服务端启动时自动初始化 VNC 服务(Windows)
- 打包脚本添加时间戳后缀
- 新增服务端日志功能,自动记录到时间戳命名的
.log文件
- 新增 rsync 双向增量同步
- 新增 RFB 文件传输协议(含断点续传)
- 离线内网工控机远程维护
- 无法安装 SSH 的封闭系统
- 临时性的命令执行需求
- 跨平台(Windows/Linux)统一工具
- 大文件增量同步(rsync 模式)
- 不稳定网络下的文件传输(RFB 断点续传模式)
- 需要图形化远程桌面的工控机维护(VNC 模式)
- 公网暴露的生产环境
- 高并发批量命令执行
- 需要交互式 TUI 程序(如 vim)
本服务设计用于离线内网环境,不提供身份认证。如需增强安全性,建议:
- 在前端增加反向代理(如 Nginx)配置 Basic Auth 或 IP 白名单
- 通过 VPN 或专线传输
- 对敏感文件传输启用 TLS(HTTPS)
- VNC 远程桌面默认无密码,建议在受控网络中使用
# PowerShell
.\build.ps1
# CMD
.\build.bat输出示例:http_shell_cli_vnc_20260519_132801.exe(约 12MB)
# 整理依赖
go mod tidy
# 编译(带时间戳)
go build -ldflags "-s -w" -o http_shell_cli_vnc_$(date +%Y%m%d_%H%M%S).exe .# 交叉编译 Windows 版本(在 Linux/macOS 上)
GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -o http_shell_cli_vnc.exe .
# 交叉编译 Linux 版本
GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o http_shell_cli_vnc .| 依赖 | 用途 |
|---|---|
golang.org/x/net/websocket |
noVNC WebSocket 代理 |
golang.org/x/sys/windows/registry |
Windows 注册表操作(VNC 配置) |
golang.org/x/text/encoding/simplifiedchinese |
Windows GBK 编码转换 |
github.com/evangwt/go-bufcopy |
VNC 代理数据拷贝 |
github.com/pkg/errors |
错误处理增强 |
MIT License