ttyd 网页终端共享故障排查指南5 类常见报错速查定位【免费下载链接】ttydShare your terminal over the web项目地址: https://gitcode.com/gh_mirrors/tt/ttydttyd 是一个通过网页共享终端会话的轻量级命令行工具本地敲一条命令浏览器里就有一个完整的、支持中文输入和文件传输的终端。听起来省事但真上线后端口被占、SSL 握手失败、认证配错、长连接乱断这些坑一个都少不了。下面把故障按起不来 → 连不上 → 连上不可用 → 用久了变差四个阶段收敛归类每类收 2~3 个高频问题每个都给可直接敲的命令和验证方法。先对号入座再动手。常见故障速查表你看到的现象最可能原因跳转定位stderr 打印Address already in use后进程退出7681端口被占用§1.1远程访问http://IP:7681超时或拒绝连接防火墙 / 安全组没放行端口§2.1反代后页面 404终端空白base-path 没配-b§2.2反复弹 Basic 登录框输对了也不进密码含特殊字符 / 浏览器缓存旧凭据§2.3能看输出但敲键盘没反应默认只读没加-W§3.1终端窗口一闪就关启动命令不存在§3.2新客户端连不上达到-m上限预期行为§3.3放着不动过一会儿就断空闲 ping 超时§4.1一、起不来进程秒退或压根没监听 先看这一类——进程活不下来后面的一切都谈不上。三个坑都集中在启动参数这一层排查成本最低优先从这里下手。1.1 一句话定位端口占用报错原文bind: Address already in use原因简析libwebsockets 在绑定默认端口7681时发现该端口已经被别的进程占了——可能是一次没退干净的旧 ttyd也可能是完全不相干的服务。这类报错和 ttyd 本身没关系纯粹是端口冲突。解决命令ss -tlnp | grep 7681这条命令列出占用7681的进程 PID先搞清楚是谁占了。确认是旧的 ttyd 就干掉它kill -9 PIDPID换成上一步拿到的进程号释放端口。嫌麻烦的话直接换端口更省事ttyd -p 8080 bash用-p指定新端口绕开冲突。如何验证重新运行后终端应打印Listening on port: 8080浏览器打开http://localhost:8080能加载出终端页面说明端口已正常监听。1.2 启动参数写错进程直接退出报错原文ttyd: invalid value for port: abcttyd: invalid credential, format: username:passwordttyd: missing start command原因简析这几条都来自 src/server.c 的main()getopt_long解析参数时任何非法值端口不是数字、credential 缺冒号、压根没给启动命令都会fprintf(stderr, ...)然后立刻退出进程根本进不到监听阶段。解决命令最常见两种ttyd -c admin:pass123 bash用-c传用户名:密码注意必须带冒号ttyd -c admin bash这种缺冒号的写法会直接报 credential 错。ttyd -p 8080 bash确认命令写全——只写ttyd -p 8080而漏掉后面的bash就会报missing start command。如何验证ttyd -h这条命令打印完整帮助对照每个选项的格式要求再正式跑一次看到Listening on port: ...即启动成功。1.3 Windows 下 ConPTY 初始化失败报错原文ERROR: ConPTY init failed! Make sure you are on Windows 10 1809 or later.原因简析Windows 10 1809 之前的内核没有CreatePseudoConsole函数。src/pty.c 里conpty_init()通过动态加载kernel32.dll再查找该符号找不到就返回 false进程直接退出。这是系统版本问题不是 ttyd 的 bug。解决命令升级操作系统到 Windows 10 1809 或更高版本或换一台满足要求的机器。ttyd 侧没有可绕过的开关。如何验证重新运行后不再出现 ConPTY 报错能看到Listening on port: 7681说明 ConPTY 初始化通过。进程能活下来之后接下来最容易出现的问题是进程明明在跑浏览器却连不进来这是下一类。二、连不上进程活着浏览器打不开 服务端日志清清楚楚写着Listening on port: 7681可就是访问不到。这一类九成不是 ttyd 的锅而是它和浏览器之间的那条链路上有人把路堵了。2.1 防火墙或安全组挡了端口报错原文 / 现象服务端日志显示Listening on port: 7681但远程浏览器访问http://IP:7681一直转圈最后超时或拒绝连接。原因简析本地curl能通、远端不通基本可以锁定在防火墙或云平台安全组上。端口在系统层被拦和 ttyd 的配置无关。解决命令firewall-cmd --list-ports查看当前放行的端口列表firewalld 环境确认7681在不在。firewall-cmd --add-port7681/tcp --permanent firewall-cmd --reload永久放行7681并重新加载规则让配置生效。如何验证在客户端机器上执行curl -v http://IP:7681返回 HTTP 200 并带出 HTML 内容说明端口已真正打通。2.2 反向代理 base-path 没配报错原文 / 现象Nginx 反代 ttyd 后页面 404或页面能加载但终端区域一直空白。原因简析走反代时请求路径带了前缀比如/terminal/而 ttyd 默认按根路径处理于是返回 404WebSocket 握手也因路径对不上被拒。src/server.c 里所有端点/、/ws、/token都要靠 base-path 统一加前缀。解决命令ttyd -b /terminal bash用-b把 base-path 设成反代前缀ttyd 会自动给所有端点补上该前缀。如何验证访问http://IP/terminal/能看到终端页面打开浏览器 DevTools 的 Network 面板看到/terminal/ws状态为101 Switching Protocols即握手成功。2.3 认证失败被反复弹登录框报错原文服务端日志WS authentication failed with token: ***原因简析src/protocol.c 里check_auth()做的是严格的字符串比对把客户端Authorization: Basic b64头里Basic之后的部分和-c传入的用户名:密码做 base64 后逐字节比较。密码里含冒号会破坏user:pass的解析浏览器缓存了旧凭据也会让比对失败于是反复弹框。解决命令ttyd -H X-Auth-User bash用-H把认证交给反向代理反代在请求头里带上X-Auth-Userttyd 只校验该头是否存在彻底绕开 Basic 认证的解析坑。若仍用-c先确认密码里没有:并在无痕窗口里访问一次清掉缓存的旧凭据。如何验证无痕窗口访问一次即进入终端服务端日志打印WS /ws - client_ip, clients: 1说明连接已建立。连上了但终端用起来不对劲——能看到输出却敲不动、或窗口一闪就没这是第三类。三、连上不可用页面开了终端却不对劲 ️网络通了、页面开了但终端要么只读、要么闪退。这类问题最容易让人误以为连上了就好了实际上差一个参数或一个命令路径。3.1 终端只读敲键盘没反应报错原文启动日志警告The --writable option is not set, will start in readonly mode原因简析ttyd 默认是只读模式src/server.c 的print_config()会主动打印这条警告。只读意味着能看输出但INPUT消息会被直接丢弃src/protocol.c 里if (!server-writable) break;所以敲键盘没任何反应。解决命令ttyd -W bash加-W开启可写。如何验证启动日志里不再出现 readonly 警告浏览器终端里敲whoami、ls能正常执行并回显输出。3.2 命令不存在终端一闪而过报错原文终端窗口里bash: xxx: command not foundexecvp failed原因简析src/pty.c 的pty_spawn()用forkptyexecvp拉起命令。命令找不到时execvp返回 -1子进程_exit(-errno)会话立刻结束页面表现为闪一下就关了。解决命令which bash确认命令在 PATH 里确实存在。要用不在 PATH 里的程序写绝对路径ttyd -W /usr/bin/zsh如何验证终端稳定保持打开不闪退执行echo $SHELL能返回预期的 shell 路径。3.3 客户端超限新连接被拒报错原文服务端日志refuse to serve WS client due to the --max-clients option.原因简析这是预期行为不是故障。src/protocol.c 在连接过滤阶段检查client_count max_clients达到上限直接拒绝新连接保护服务端不被压垮。解决命令ttyd -m 20 bash按实际并发需求调大上限。如果上限是故意设的比如做演示只想给少数人那被拒本身就是正确结果不用修。如何验证日志里clients:计数能涨到 20 而不被拒第 21 个连接仍会被拒——这正符合-m 20的预期。跑短期演示没问题但要是挂着长期运行时间一长就会暴露另一类更隐蔽的毛病。四、用久了变差跑得越久越不对劲 这一类没有明显的报错表现是时好时坏。多数和空闲超时、进程生命周期有关优先怀疑网络层再回头查 ttyd 参数。4.1 长连接被空闲断开报错原文 / 现象终端放着不动过一会儿突然断开刷新才能重连。原因简析libwebsockets 的 retry 策略带secs_since_valid_ping默认 5 秒和secs_since_valid_hangup默认 ping 间隔 7 秒超时就主动断开NAT 超时、WiFi 休眠也会让底层 TCP 悄悄断掉。这类过一阵就断通常是网络层心跳问题不是 ttyd 自身。解决命令ttyd -P 10 bash用-P把 WebSocket ping 间隔从默认 5 秒调到 10 秒src/server.c 里retry.secs_since_valid_ping interval减少心跳包数量。若调了还频繁断优先查网络而不是继续改 ttyd。如何验证ss -tlnp | grep 7681确认监听正常终端放置 30 分钟以上不再自动断开客户端 DevTools 里 WS 连接状态保持 101。4.2 客户端全退后进程还占着端口报错原文 / 现象所有浏览器都关了ttyd 进程还在跑端口一直被占着。原因简析默认行为就是最后一个客户端断开后进程继续存活方便复用。只有--once只接一个客户端断开即退和--exit-no-conn全部断开即退才会主动退出src/protocol.c 里LWS_CALLBACK_CLOSED处理。解决命令ttyd -o bash一次只接一个客户端断开即退出适合临时演示。ttyd -q bash所有客户端断开后退出适合需要复用端口、按连接释放的场景。如何验证关闭所有浏览器标签后执行ps aux | grep ttydttyd 进程消失日志打印exiting due to the --once/--exit-no-conn option.说明生命周期符合预期。自查无果收齐信息再找人省一半时间上面四类覆盖了绝大多数现场问题。如果你的情况没被覆盖别急着问人——先把信息收齐再去找维护者或社区来回追问才是最耗时间的。先记下这几项ttyd -v拿到版本号这是排查的第一手依据。uname -a记录操作系统与内核版本。ttyd -d 1 bash用-d 1把日志级别降到只输出错误src/server.c 里-d设置 libwebsockets 日志级别数值越小越安静把完整 stderr 截下来。再补上浏览器 DevTools 里 Console 和 Network 的报错截图以及完整的启动命令含所有参数。搜索关键词建议直接搜报错原文如ttyd Address already in use、ttyd WS authentication failed加参数名搜如ttyd -b base-path 404在官方 Issue 区搜同样报错网络与认证类问题多数有现成答案官方渠道项目 Issue 区标题写清现象连不上 / 认证失败正文贴全版本 系统 启动命令 日志四件套别只写一句不工作社区讨论描述里附上ttyd -h的输出方便对方确认你当前版本支持的参数集提 Issue 前的信息清单ttyd -v版本号uname -a系统输出完整启动命令-d 1日志关键片段20 行左右浏览器名称 版本 控制台报错截图是否走反代 / 防火墙若是附上反代配置片段一份材料齐了再发出去维护者基本能直接定位省掉来回追问的功夫。【免费下载链接】ttydShare your terminal over the web项目地址: https://gitcode.com/gh_mirrors/tt/ttyd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?