返回博客列表
2025年12月03日
5 min read

端口映射:Empty reply from server

Xshell端口映射报错:Empty reply from server的排查指南。

端口映射:Empty reply from server

端口映射:Empty reply from server

SSH 隧道状态 Open 却无法连接?排查 "Empty reply from server" 的指南

🛑 问题现象

当你尝试通过 SSH 隧道访问远程服务时,遇到以下诡异场景:

  1. 客户端显示正常:Xshell/Putty 的隧道状态栏显示绿色的 “打开 (Open)”
  2. 本地连接失败:在本地浏览器或终端访问 localhost:port 时,请求被挂起或立即中断。
  3. 报错特征
    • curl 报错:curl: (52) Empty reply from server
    • 服务器端正常响应
    • 浏览器报错:ERR_CONNECTION_RESET 或无响应。

这表明管道已打通,但水流在流出管道口的那一刻被阀门截断了。以下是标准化的排查流程。


第一阶段:服务端自检

目的:确保远程服务器上的服务本身是健康的,且监听端口正确。

1. 确认端口监听状态

在服务器终端执行,检查服务是否在监听,以及绑定了什么 IP,下面以我在vllm部署模型推理时的8019端口为例。

netstat -tunlp | grep 8019
  • ✅ 正常情况:显示 0.0.0.0:8019(监听所有 IPv4 地址)或 :::8019(监听所有 IPv6 地址)。
  • ⚠️ 隐患:如果只显示 127.0.0.1:8019,说明服务只允许服务器内部访问,隧道转发时目标必须严格填写 127.0.0.1

2. 服务端内网自测

在服务器内部模拟客户端请求,确认服务有响应。

# 如果是 Docker 服务,通常有 HTTP 接口
curl -v http://127.0.0.1:8019/v1/models # 换为你自己服务器的请求方式
  • 结果分析:如果有 JSON 返回或 HTTP 200/404 响应,说明服务存活。如果连这一步都 Connection refused,请先去修 Docker/服务本身。

第二阶段:隧道配置

目的:规避 IPv4/IPv6 协议栈冲突,确保隧道“目标地址”明确。

3. 获取服务器内网 IP

很多时候 localhost 在隧道转发中存在解析歧义(Docker 绑 IPv6 而 SSH 转发 IPv4),使用确定的内网 IP 是最稳妥的方案。

ip addr
# 或者
ifconfig
  • 操作:找到 eth0ens 网卡的 IP,例如 192.168.0.22172.17.0.1

4. 修正 SSH 客户端规则

回到你的 SSH 客户端(如 Xshell),修改隧道规则配置:

  • 源主机 (Source): localhost
  • 侦听端口: 8019 (本地端口)
  • 目标主机 (Destination): 填入上一步获取的内网 IP (如 192.168.0.22),不要填 localhost。
  • 目标端口: 8019 (远程服务端口)

⚠️ 注意:修改后必须重启会话(断开并重新连接)才能生效,继续在本地检查是否能够响应。


第三阶段:权限与防火墙

目的:如果前两阶段都正常,本地仍然报错 Empty reply,说明操作系统内核或 SSHD 进程拦截了流量转发。

5. 排查 SELinux(常见阻断)

CentOS/RHEL 系统默认开启 SELinux,它会禁止 SSH 进程将数据转发到非标准端口(如 8019)。

  • 快速验证(临时关闭)
    setenforce 0
  • 测试:此时在本地再次 curl。如果通了,说明凶手就是 SELinux。

6. 排查 SSHD 配置

这是最容易被忽略的配置。服务器的 SSH 守护进程 (sshd) 可能配置了禁止 TCP 转发。

操作步骤:

  1. 打开配置文件
vi /etc/ssh/sshd_config
  1. 快速定位配置项(Vi 技巧): 打开文件后,直接在键盘输入以下指令进行正则搜索:
/AllowTcpForwarding
  • 按下 Enter 键,光标会跳到第一个匹配项。
  • 如果发现是注释行(以 # 开头),按下键盘上的 n 键(Next),查找下一个匹配项。
  1. 检查与修改: 找到该行后,检查参数是否为 yes。如果是 no 或者被注释掉(默认有时为 strict 模式),请修改为:
AllowTcpForwarding yes
  1. 保存退出: 按 Esc -> 输入 :wq -> 回车。

  2. 重启 SSH 服务(必须执行):

   systemctl restart sshd

第四阶段:本地最终验证

目的:确认问题解决。

在本地终端执行:

curl -v http://127.0.0.1:8019/v1/models # 换为你自己服务器的请求方式
  • 成功标志:看到 HTTP 响应头和具体的 JSON 数据。
  • 失败标志
    • Connection refused:隧道没建好(检查 Xshell 是否 Open)。
    • Empty reply:回到第三阶段继续查防火墙/权限。

📝 总结

遇到 SSH 隧道“通而不达”的问题,可以进行下面尝试:

  1. 先测服务端,确保服务活。
  2. 再换内网IP,避开回环坑。
  3. 关掉SELinux,权限放行快。
  4. 搜AllowTcp,开启转发权。

推荐阅读

发表评论

欢迎留下你的想法和见解,使用 GitHub 账号登录即可参与讨论