首页 / 资讯中心 / 文章详情

自建Web SSH:用Termix把SSH会话搬进浏览器,随时随地远程运维

自建Web SSH:用Termix把SSH会话搬进浏览器,随时随地远程运维 ★ FEATURED ARTICLE
说个最近的遭遇人在外面手机上收到服务器告警磁盘快满、日志刷屏、进程被挤出。我身边没电脑手机上的终端客户端在那种情况下根本用不上。折腾了半天我下决心给自己搭一套能放在浏览器里、随时随地打开就能连的 Web SSH。最后配合 Termix 把 SSH 会话桥接到了网页端整个过程踩了不少坑。这篇是完整记录想做这件事的原理、部署方式、安全加固和排错经验都在里面。适合跟我一样经常不在电脑前的人也适合正在选型的小团队运维同学参考。1. 为什么我最后选择自建 Web SSH而不是硬凑合1.1 传统 SSH 在移动场景下的四个尴尬我不是说命令行 SSH 不好它在正经办公环境里无可替代。但随时随地管服务器这六个字直接把传统方式的脸打肿了第一客户端依赖。公司电脑、客户现场的机器、朋友借的笔记本不可能每台都装好 SSH 客户端。遇到 Windows 默认环境更强命令端都没法直接用。手机端的 SSH 应用倒是不少可屏幕小、键盘输入难受、复制粘贴还经常乱套。第二网络环境限制。很多访客网络只放行 80 和 443 端口SSH 默认的 22 端口直接被掐死。有的公司出口代理还要审计流量非标准端口很容易触发告警。第三多台机器管理碎片化。我得同时维护好几台服务器IP、端口、密钥、用户名光这些信息就够记一堆。没有一个统一的入口每次都是临时去翻记录效率极低。第四会话稳定性。网络一波动SSH 会话断掉正在跑的任务可能跟着遭殃。虽然进程层面有 tmux、screen 顶着但你在移动端重新连回去的体验依然不痛快。1.2 Web SSH 的适用人群与场景边界这套方案不是要取代桌面 SSH它解决的是轻量、临时、跨设备的问题。最适合三类人个人开发者 / 独立站长服务器不多但经常外出需要快速看一眼服务状态、重启容器、看日志浏览器就能解决。小团队运维成员需要共用一个管理入口但不想给每个人都开服务器系统账号又想留操作记录。混合环境使用者公司内网有一批机器家里有一批机器想要一个统一的管理页面。不适合谁如果你的运维流程已经重度依赖堡垒机、审计系统或者有严格的等保需求那就没必要自建直接走企业级方案。Web SSH 适合够用就好的人。1.3 别人家的方案 vs 自己搭市面上现成的方案并不少云厂商控制台里基本都有网页终端也有在线 SSH 工具网站。但我个人不愿意接受两个限制一是账号系在特定平台上换一家云厂商、换一台非公有云机器就用不了二是中间链路自己不可控在线工具相当于把服务器会话交给了第三方安全性我说服不了自己。Termix 这种自建方案最大的价值就是自主权会话数据跑在自己控制的链路上认证规则自己定日志自己留。虽然搭建花费一些时间但长期用下来很值。2. Termix 的工作机制SSH 是怎么被塞进浏览器的2.1 整体结构三个角色各司其职在真正动手之前我建议先花十分钟理解这套东西的运行逻辑。用一句话概括浏览器负责显示终端界面服务端负责代替你完成 SSH 协议通信两者之间用实时通道连接起来。拆开看分成三层前端层浏览器里跑的终端模拟组件负责把字符流渲染成一个可交互的终端窗口同时把键盘输入捕获并发送出去。桥接层也就是 Termix 服务端本身接收浏览器的实时连接请求解析会话指令然后在服务器本地创建一个真正可用的 SSH 会话。目标层你要管理的目标服务器Termix 服务端以普通 SSH 客户端的方式连接它。整个过程里浏览器并没有直接跟目标服务器建立 SSH 连接它只跟 Termix 服务通信。2.2 一次会话的完整数据流我画一下我在脑子里理的流程对这个部分新手容易晕你在浏览器里打开 Termix 页面先做登录认证服务端发给你一个有效的会话令牌。你在页面里输入目标服务器的地址、端口、用户名或者选择一个预配置的主机。Termix 服务端收到请求后校验权限然后替你执行一次 SSH 连接。连接建立后目标服务器的 stdout 输出被编码成数据帧通过实时通道推给浏览器。浏览器里的终端模拟组件把数据帧还原成文字和颜色显示在页面上。你在页面敲下的每个按键也被封装成数据帧回传到服务端服务端把它写入 SSH 会话的标准输入。实际用下来感觉就和本地终端几乎一样。2.3 为什么要用 WebSocket 而不是普通 HTTP 请求这里解释一个关键选型点。SSH 会话是双向、持续、实时的通信每个按键都要很快响应服务端的输出也要连续推给浏览器。如果用普通 HTTP 轮询你每敲一个字符就要发一次完整请求服务端有输出还要另外拉一次延迟和资源消耗都受不了。Termix 的桥接通道用的是 WebSocket。它的核心优势是建立一次连接之后双向推送数据不需要反复握手也不存在短轮询的延迟问题。体验上接近原生 SSH能做到输入即时回显、输出持续滚动。在反向代理层处理的关键就是把这个 WebSocket 升级请求正确放行后面第五节我会详细讲踩坑过程。2.4 会话管理与终端类型协商还有一个容易被忽略的细节是终端类型协商。传统 SSH 会自动协商一个终端类型比如xterm-256color影响颜色显示和快捷键行为。Web SSH 同样要做这个事情Termix 在建立会话时会带上预设的终端类型保持颜色主题、光标定位、快捷键组合能正常工作。如果协商不对最常见的症状是top、htop的界面刷不出来或者 vim 里的方向键变成字符A、B、C、D。3. 从零搭起Termix 部署全流程记录3.1 部署前的准备工作先说硬件和环境需求。我用的是一台 1 核 1G 的小机器CentOS 7 系统内存小了点但只跑 Termix 完全够。如果你要同时承载多人使用建议 2 核 2G 起步。需要一个域名用来配置 HTTPS不然浏览器里的部分高级能力比如剪贴板读取会被限制。域名解析到这台机器上并确保 80、443 端口在防火墙里放行。注意放行 443 端口之后如果这台服务器本身就是你的目标机器之一请确认你没有把 22 端口暴露到公网。Termix 服务本身应当通过系统防火墙只允许本地回环访问真正对外暴露的只有 443。3.2 安装与初始化配置Termix 的安装包跟一般软件不大一样不同版本的目录结构和命令会存在差异。下面这套步骤是我基于常见实践整理的通用流程你拿到具体版本后要对照官方说明调整目录和配置文件路径。# 1. 创建独立运行用户避免以 root 身份常驻服务 useradd -m -s /bin/bash termix # 2. 切换到该用户并下载安装包解压到指定目录 su - termix mkdir -p ~/termix tar -xzf termix-release.tar.gz -C ~/termix cd ~/termix # 3. 生成初始配置模板 ./termix init初始化完成后目录下会有一个termix.yaml配置模板。我个人的习惯是把配置项按三块分监听地址、认证策略、会话上限。最开始什么都不用想复杂只改监听地址server: listen: 127.0.0.1:8080 # 只监听本地回环 session_timeout: 1800 # 会话空闲超时单位秒 auth: mode: password # 先用密码登录后边再加 TOTP session_ttl: 7200 # 登录态过期时间用./termix start启动服务telnet 127.0.0.1 8080能通就说明基础服务起来了。这时浏览器访问需要先想办法打通外网访问路径推荐的做法是交给反向代理来处理。3.3 初始化配置的可操作细节我第一次搭的时候在配置上犯过一个低级错误把监听地址配成了服务器公网 IP。这样 Termix 服务本身直接暴露在公网省掉反向代理的部署看起来更简单但后续想加 HTTPS、做访问控制就非常痛苦而且 8080 端口很容易被扫描工具盯上。正确做法是只监听 127.0.0.1让外部流量经过反向代理转发进来。这样 Termix 永远只面对本机的 Web 服务器公网攻击者看不到它。3.4 反向代理与 HTTPS 配置我用的主机的 Web 服务器是常见开源方案给 Termix 加一段反向代理配置。这里有个关键要求必须放行 WebSocket 升级请求。以我的配置片段为例server { listen 443 ssl; server_name term.example.com; ssl_certificate /etc/ssl/term/term.example.com.pem; ssl_certificate_key /etc/ssl/term/term.example.com.key; location /termix/ { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }如果你的 Web 服务器可以自动申请和续期 HTTPS 证书那更容易直接把域名指过来配一个反向代理就好。注意http与https的自动跳转、请求体大小限制要放开SSH 会话传输的流式数据并不大不会被 Nginx 限制困扰但 WebSocket 帧的读取超时要给足。默认超时经常是 60 秒终端长时间没有输出时会被主动断开建议把读取超时调大例如 300 秒以上。配好后浏览器访问https://term.example.com/termix/看到登录页说明整套链路已经通了。4. 公网暴露的 Web SSH这些安全加固必须做4.1 我只跑了两天就被扫描了这套服务上线后我特意观察了几天日志。第一天就有来自不同来源的扫描请求试图猜登录口令。这给我提了一个醒Web SSH 是价值非常高的攻击目标因为它一旦被攻破等于把服务器权限交出去了。所以安全这块不是可选项是必选项。攻击面主要有三块登录前暴力破解、弱口令尝试、未知路径探测。会话中令牌泄露、被中间人截获、多用户会话隔离不足。系统层Termix 服务本身上线后如果某个未知接口被调用了安全隐患会放大。4.2 登录认证升级从单层密码到两层保护密码登录在公网上撑不了多久。我的建议是至少做到两层第一层密码验证第二层动态验证码。Termix 支持在登录认证基础上挂载动态口令验证我用的是常见的开源动态口令库生成方式是基于时间的一次性密码。手机端装一个标准认证类应用扫描 Termix 生成的二维码以后每次登录都要输入 6 位动态码。这样做的好处是即使密码因为某种原因泄露没有动态码也进不来。我还顺手做了失败次数限制同一 IP 连续失败 5 次就临时封禁 15 分钟。这个可以在 Web 服务器层实现也可以在 Termix 内启用看各自版本支持情况。4.3 IP 白名单、访问路径与来源控制如果你的使用场景相对固定可以在 Web 服务器层加 IP 限制。只允许公司出口 IP、家里宽带 IP 访问/termix/路径其它来源一律返回 403。这个策略简单有效能过滤掉 80% 的扫描流量。如果活动范围确实不固定至少可以设置账号级登录地点提醒登录成功之后把本次来源 IP 显示在页面上发现不对立刻手动失效全部会话。4.4 会话隔离与超时策略多人共用这套系统时每个用户的 SSH 会话必须相互隔离。Termix 的每个连接在服务端有独立的会话映射互不干扰。我配置了空闲超时自动断开默认为 30 分钟如果 30 分钟内没有键盘输入会话自动终止避免人走开以后会话被接管。注意这里的会话超时和系统层的 idle session 不是一回事。系统层的会话可能还会因为服务端线路问题悬挂着Web SSH 的会话超时只是指浏览器与 Termix 之间的连接。真正要杜绝悬挂连接建议同时配合使用ClientAliveInterval这类 SSH 服务端参数。4.5 审计日志是最容易被忽视的一环我建议从第一天就开启操作日志。这个日志至少需要记录四个要素谁、在什么时间、连了哪台机器、执行了什么操作。如果只记录登录成功但没记录具体命令出问题的时候你连攻击者做了什么都不知道。Termix 大部分版本可以配置将日志输出成文本落盘。我的做法是直接写到日志目录下然后定期归档。终端输出和键盘输入如果都记录日志文件会增长得很快但如果连续记录两个月对磁盘占用完全可接受换来的排查能力非常值得。风险点常见攻击方式我采用的加固措施登录口令暴力破解、撞库密码 动态验证码失败次数限制访问来源全网扫描Web 服务器层 IP 白名单非白名单 403 拒绝会话劫持令牌泄露、中间人强制 HTTPS会话空闲自动过期越权操作账号共用、权限过大独立系统账号映射按需分配主机权限事后溯源证据缺失记录登录时间、来源、命令输出、目标主机5. 实测踩坑记录从能用到好用的关键修复5.1 复制粘贴失灵和方向键乱码第一次跑通之后我用 vim 编辑文件发现方向键每次都会插入字符A、B、C、D复制粘贴也完全不受控。一开始以为是 Termix 的问题排查之后确认是终端类型协商的问题。因为某些终端组件默认以极小型的终端类型连接老旧的程序不支持功能键转义序列。解决方式有两种把终端类型固定为xterm-256color在 Termix 的会话配置里指定终端类型参数。检查浏览器页面是否启用了正确的终端模拟组件的键位映射有些组件默认不开启应用光标模式。真正把终端类型改成xterm-256color之后vim 的体验立刻正常了。复制粘贴要注意页面上提供的安全上下文权限首次使用会要授权剪贴板读取允许一次后就不再弹。5.2 WebSocket 被反向代理掐断的完整排查链路这个问题很典型值得写出来。上线前一天我测试一切正常第二天再打开页面输入密码后能建立会话但终端没有任何输出几秒后提示连接已断开。看 Termix 服务端日志发现浏览器发起 WebSocket 升级请求服务端已经接受了但反向代理层没有正确转发。排查过程是这样的先用浏览器的开发者工具抓请求确认 WebSocket 握手请求返回了 200 而不是 101。200 说明反向代理没有把它当一个升级请求而是当成普通 GET 请求处理了。检查反向代理配置发现我第一版配置里没有设置Upgrade和Connection请求头。最初补上了Connection upgrade的配置接上发现还是不稳因为代理的读取超时太短长连接闲置一会儿就被切断。最后调整代理读取超时参数把超时加大问题彻底消失。这里最容易被忽略的是很多反向代理默认不保留长连接升级请求一旦走默认处理WebSocket 就废了。这种问题不是一眼能看出来的要认真翻一下层层的日志。5.3 多人同时登录同一主机的会话串扰有同事在同一时间登录同一台目标服务器出现了一种奇怪现象两边敲的命令偶尔会跑到对方会话里。排查后发现问题不在 Termix 本身而是我们两个人用的系统账号是同一个。当两个 Web SSH 会话映射到同一个系统用户时服务端交互式会话会冲突。解决办法是给每个人分配独立的系统账号并且 Termix 配置里把账号与主机访问权分开控制。如果只是临时用一下至少要让每个人手动指定--identity参数连接不同会话避免复用同一个默认账号。5.4 手机端体验优化的一些细节浏览器能开网页就能连服务器但手机端有几个地方值得打磨把页面添加到主屏幕全屏显示体验接近原生应用。开启页面自带的字号调整选项手机端字号适中才不费眼。把常用主机预存在 Termix 的配置里连接时只需要点一下选择不用敲 IP。开小键盘出来会很占屏尽量用终端操作少开输入法。我实际在手机上用它修过一次配置错误人在地铁上服务告警我打开手机浏览器点两下进了页面改掉了配置服务恢复。以前这种场景基本是等回电脑再说。一些我最后想分享的使用习惯Termix 这套体系用了几个月后我总结了几条自己的习惯。现在每周都会检查一次登录日志看看有没有陌生 IP 的尝试记录。动态验证码让密码泄露的风险变低但并不能完全代替定期更换密码。所有目标服务器的密钥尽量都采用密钥登录并且 Termix 服务端保存密钥文件的位置要设置严格权限其它用户不可读。如果你准备给团队使用建议最开始就约定账号命名规范和目标主机分组规则不然人一多就会乱。如果你已经有一台可以访问公网的服务器搭这套东西一两个小时就能搞定真正花时间的其实是被攻击之后怎么应对。能把这套东西认真跑起来的人运维效率会提升很大。希望你也能从这套方案里受益。
阅读完成 · 觉得有帮助?
咨询建站