DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

SSH -R 指定其他回环地址后仍监听 127.0.0.1

客户端请求 -R 127.0.2.3:23000:127.0.0.1:8080,远端却只在 127.0.0.1:23000 上监听。SSH 已经登录,转发也能通过默认回环地址访问,但不能按预期用多个回环地址区分同一端口。

客户端请求 -R 127.0.2.3:23000:127.0.0.1:8080,远端却只在 127.0.0.1:23000 上监听。SSH 已经登录,转发也能通过默认回环地址访问,但不能按预期用多个回环地址区分同一端口。

在 OpenSSH 中,远端监听地址由服务端的 GatewayPorts 策略约束。默认 no 并不意味着客户端可以任选一个 127.* 地址;请求其他回环地址时,也可能回到默认回环监听。本文针对这个地址被改写的场景,示例服务端为 Linux,使用支持 Match、GatewayPorts clientspecified 和 PermitListen 的 OpenSSH。

两个地址分别属于哪一端

下面的命令应从运行目标服务的客户端发起,账号和域名是占位值:

ssh -N -v -S none -o ExitOnForwardFailure=yes \
  -R 127.0.2.3:23000:127.0.0.1:8080 tunneluser@relay.example.com

127.0.2.3:23000 是希望在远端 SSH 服务器建立的监听;最后的 127.0.0.1:8080 则由客户端连接,指向客户端自己的回环服务。改变后者不会改变远端监听地址。

排查时不加 -f,便于看到建立转发时的消息;-S none 避免复用已有连接。ExitOnForwardFailure=yes 能让监听建立失败时退出,但不能证明目标应用可用,也不能代替查看实际监听地址。

在远端 Linux 主机查看:

ss -lnt 'sport = :23000'

如果确实有监听,但地址是 127.0.0.1 或 ::1,继续核对服务端策略。若没有监听,或提示地址占用、不能分配地址,应分别处理端口冲突、目标地址在该系统上的可用性和转发权限;不要把所有建立失败都归为 GatewayPorts。

在服务端允许这个明确的监听请求

要修改的是远端 /etc/ssh/sshd_config 或它实际包含的配置文件,不是客户端的 ~/.ssh/config。客户端的 -g 也不能替代服务端的远端转发策略。

GatewayPorts yes 会强制通配地址监听,可能把本来只打算留在回环上的服务暴露到其他接口。这里应使用 clientspecified,并限制账号和允许的监听端点。备份原配置后,在合适位置加入或调整:

Match User tunneluser
    GatewayPorts clientspecified
    PermitListen 127.0.2.3:23000
Match all

这段配置只演示监听策略,不创建账号,也不授予原本禁止的转发能力。已有 DisableForwarding、AllowTcpForwarding 或密钥上的转发限制仍需符合实际授权;不要为了让隧道通就统一删掉限制。PermitListen 管的是请求监听的地址与端口,也不是完整的账号隔离方案。

明确写出 127.0.2.3 很重要。客户端不指定监听地址时会请求 localhost,它与显式 IP 并非同一个许可项。多个 Match、包含文件及已有设置可能影响最终结果,不能只确认新增片段存在。

检查有效配置后重新建立隧道

在服务端保留当前管理连接,先检查配置。以下路径按实际 sshd 安装位置调整,若服务使用其他配置文件,两条命令都应带上对应的 -f:

sudo /usr/sbin/sshd -t
sudo /usr/sbin/sshd -T \
  -C user=tunneluser,addr=192.0.2.10,host=client.example.com

192.0.2.10 和 client.example.com 要替换为实际客户端地址及匹配条件使用的主机名;如果配置还按服务器地址、端口等条件匹配,也要提供对应连接条件。输出应显示预期的 gatewayports clientspecified 和限定的 permitlisten,并核对其他转发控制项。

只有语法检查通过后,才通过系统原有服务管理方式重载 SSH 服务。Linux 发行版的服务名可能是 ssh 或 sshd,应使用现有管理方式,不要另启一个守护进程。重载不会把已经建立的旧隧道重新绑定;结束本次测试隧道,再用上面的客户端命令重新连接。

验收地址与应用两层结果

重新查看远端监听,确认是 127.0.2.3:23000,而不是 0.0.0.0:23000、[::]:23000 或错误的回环地址。随后在远端用目标服务对应的协议访问该端点,检查数据是否到达客户端的 127.0.0.1:8080。仅看到 SSH 进程还在运行,不代表这一整条路径成功。

如果只是希望多个隧道互不冲突,也可以保持默认策略,为它们分配不同远端端口;没有必要为此扩大接口暴露范围。确实需要其他回环地址时,先确认操作系统支持在该地址上绑定,不必盲目创建一批虚拟网卡。

回退时先关闭本次建立的隧道,恢复修改过的服务端片段,重新检查并重载,再确认测试端口不再监听。恢复配置本身不会自动清除已有连接上的转发。