



























今天把哪吒监控升级了一下,升级后常规图表与 Agent gRPC 状态上报均正常,唯独在后台点击 “终端管理”(路径 /dashboard/terminal/:id)时,命令行窗口死活弹不出来。直接报错404.

去翻 Nginx 的实时访问日志,抓到了这么一条记录:
"GET /dashboard/terminal/5 HTTP/2.0" 404 468 "https://nz.7zz.cn/dashboard"
这就说明请求通过 HTTP/2.0 进来了,但后端直接回了个 404。
我前后排查了几轮,从 Nginx 一路排查到被控端,最后发现被一个极度隐蔽的边缘节点拦截问题给坑了。记录一下死磕的过程。
[emerg])哪吒 v1 的在线终端强依赖标准的 WebSocket 长连接升级。一开始为了优化大流量下的性能,我顺手在 location / 里面塞了自定义的缓冲区参数:
proxy_buffer_size 128k;
proxy_buffers 4 256k;
结果在宝塔面板一保存,Nginx 语法测试直接炸了:
[emerg] "proxy_temp_file_write_size" must be equal to or greater than the maximum of the value...
原因:宝塔在全局 nginx.conf 里默认给的 proxy_temp_file_write_size 太小了。Nginx 规范规定,临时文件写入大小必须大于或等于缓冲区的最大值。
解决办法:我把这堆自定义缓冲区配置直接提到 server 块的顶部,并且显式定义 proxy_temp_file_write_size 256k;,让它变成全站统一规格,顺利通过 Nginx 测试。
哪吒新版面板对 API 路由做了重构。普通的 Web 流量走常规转发,但终端走的是专门的 WebSocket 正则路由。我在 Nginx 中引入了高优先级的正则匹配块(~* 优先级高于 /),并补全了跨域鉴权头(Origin)和连接升级头:
# 哪吒官方标准:WebSocket 相关拦截
location ~* ^/api/v1/ws/(server|terminal|file)(.*)$ {
proxy_set_header Host $host;
proxy_set_header nz-realip $http_cf_connecting_ip;
proxy_set_header Origin https://$host; # 跨域鉴权关键头
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_pass http://127.0.0.1:8008;
}
到这一步,Nginx 层的转发逻辑已经彻底通了。然而刷新浏览器去点终端,依然是 404。我当时甚至怀疑是某些老旧被控端的魔改协议或者 Docker 镜像没更新干净,结果一顿重装、强拉官方最新镜像下来,依旧没有任何卵用。
最后我把视线移向最外层的 Cloudflare,才发现问题根本不在服务器内部,而是 我之前在 CF 后台配置的“自定义错误页面(Custom Pages)”拦截了路由。
/dashboard/terminal/5,在服务器上压根没有真实的物理文件,它只是个前端虚拟路径。404 状态码。但在正常情况下,它会同时附带返回前端的 JS 引导文件,让浏览器拿到后在本地动态解析并渲染出终端窗口。404 状态码,就会自作聪明地判定“这是一个死链”,然后强行把后端原本附带的、用来初始化前端路由的 JS 数据全部抹掉,替换成了我自定义的 HTML 404 页面。结果就是前端动态脚本直接断流,浏览器根本拿不到渲染终端的核心代码。我在 Nginx 日志里看到的 404 468,其实就是请求被 CF 强行拦截干涉后的假象。
解决方式非常粗暴:
再去点在线终端,熟悉的黑色命令行瞬间秒连,丝滑无比。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。