
一、为什么要做网页 SSH?
传统 SSH 要装客户端、配环境,公共电脑 / 手机上很麻烦。网页 SSH = 浏览器打开就能连服务器,像本地终端一样用,适合运维、云服务器管理、IoT 设备调试。
二、核心原理(一句话看懂)
浏览器不能直接发 TCP 连 SSH,所以用三层转发:
前端 xterm.js 终端 ←WebSocket→ 后端代理 ←SSH 协议→ 目标服务器
- 前端:画终端、收键盘、显结果
- 后端:做中间人,转协议、保安全
- 通道:WebSocket 双向实时传输
三、必备技术栈
前端
- xterm.js:浏览器里渲染标准 Linux 终端(颜色、光标、快捷键全支持)
- WebSocket:和后端长连接、实时收发数据
后端
- Node.js + ssh2 + ws
- Python + Paramiko + websockets
- Go + golang.org/x/crypto/ssh
- Java + JSch
通信
- 前端 ↔ 后端:WebSocket(wss 加密)
- 后端 ↔ 服务器:SSH2 协议
四、完整实现步骤(手把手教学)
第 1 步:前端终端页面(纯 HTML 可直接运行)
第 2 步:后端代理(Node.js 版,复制即用)
安装依赖:
npm init -y
npm install ws ssh2const WebSocket = require('ws');
const { Client } = require('ssh2');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
console.log('前端已连接');
// SSH配置(改成你自己的服务器)
const sshConfig = {
host: '你的服务器IP',
port: 22,
username: 'root',
password: '你的密码'
// privateKey: require('fs').readFileSync('/path/key') // 密钥登录
};
const ssh = new Client();
ssh.on('ready', () => {
console.log('SSH已连接');
// 打开Shell
ssh.shell((err, stream) => {
if (err) { ws.close(); return; }
// 前端按键 → SSH
ws.on('message', (data) => {
stream.write(data);
});
// SSH输出 → 前端
stream.on('data', (data) => {
ws.send(data.toString());
});
// 关闭清理
stream.on('close', () => {
ssh.end();
ws.close();
});
});
});
// 连接SSH
ssh.connect(sshConfig);
});
console.log('WebSocket服务启动:ws://localhost:8080');node server.js五、必须掌握的进阶功能
1. 会话管理(断线重连)
- 后端给每个连接生成唯一会话 ID
- 存在 Redis / 内存,记录状态
- 前端监听
onclose,自动重连并带上 ID 恢复会话
2. 安全必须做(上线必备)
- WebSocket 必须用 wss://(TLS 加密)
- 前端先登录(OAuth/LDAP),再开 SSH
- 密码 / 密钥只在内存流转,不存日志
- 禁止高危命令:sudo、rm -rf、mkfs 等
- 全操作日志审计(存用户、时间、IP、输入输出)
3. 性能优化
- 大输出流式渲染,避免卡顿
- 数据压缩(zlib)减少带宽
- 终端大小自适应,支持移动端
六、成熟开源方案(不想自己写就用这些)
- WebSSH:Python+Flask+Paramiko,部署最简单
- GateOne:功能强,支持多用户、认证全
- shellinabox:超轻量,单文件运行
- 阿里云 / Web 终端:企业级,内网代理、权限精细
七、常见问题与排错
- 前端连不上后端
- 终端黑屏没反应
- 按键没反应
- 中文乱码
- 生产环境不安全
八、总结(最简架构)
xterm.js + WebSocket + ssh2 = 万能网页 SSH
- 前端负责界面与输入
- 后端负责代理与安全
- 通道负责实时传输
