正在阅读读懂 SSH 本地端口转发:-N、-L 与两端的 127.0.0.1
香港天气加载中…
QWeather ↗
← Back to the notebook

读懂 SSH 本地端口转发:-N、-L 与两端的 127.0.0.1

从一条脱敏命令出发,区分本地监听端口、远端目标地址和 SSH 连接;用数据流与分层验证解释终端为何安静,以及隧道建立后为什么仍可能访问失败。

01 · 一句话读懂这条命令

这是一条 SSH 本地端口转发命令:在运行命令的机器上开一个本地入口,把连接通过 SSH 通道交给远端,再由远端连接目标服务。

公开版本已脱敏

账号使用 remote_user,服务器使用示例域名 server.example.com;本地与目标业务端口分别使用 18080、8080。127.0.0.1 是解释机制所需的回环地址。实际使用时,将示例替换为自己的环境值。

以下命令保留了原命令的参数结构。它的含义是:访问本地端口 18080 时,通过 SSH 去访问服务器自身的 127.0.0.1:8080。

常见用途是通过已允许的 SSH 连接,访问没有额外向外开放的目标服务;前提是 SSH 服务器能够连接该目标,并允许相应转发。

Bash
ssh -N -L 18080:127.0.0.1:8080 remote_user@server.example.com

02 · 逐项拆开:每一段分别控制什么

命令片段含义容易混淆的边界
ssh启动 SSH 客户端,与目标 SSH 服务器建立连接并认证。SSH 连接端口由 -p 或客户端配置决定;未改配置时通常为 22。
-N不执行远端命令,适合只做端口转发。仍要认证;也不表示自动后台运行。
-L建立从 SSH 客户端一侧进入的本地转发。这里给出的是 TCP 端口转发参数。
18080在运行 ssh 的机器上监听的本地端口。是应用访问的入口,可按需要换成未占用的本地端口。
127.0.0.1由 SSH 服务器去连接的目标地址。在这个位置指服务器自己,不是运行命令的机器。
8080目标服务的实际端口。要与远端服务匹配;它不是 SSH 连接端口。
remote_user@server.example.comSSH 登录账号与 SSH 服务器地址。该账号用于 SSH 认证,不自动代替目标应用自己的登录。

参数定义可在 OpenSSH 的 ssh(1) 手册中核对:重点看 -N、-L、-p 和连接目标的写法。

03 · 先分清:究竟是哪台机器的 localhost

TCP 形式的完整写法是 -L [bind_address:]port:host:hostport。方括号表示本地绑定地址可以省略;它不是需要输入的字符。

位置谁来解释这个地址本例含义
本地应用访问的 127.0.0.1:18080运行本地应用的机器。应用连接这一端的 SSH 监听入口。
-L 中作为目标的 127.0.0.1:8080远端 SSH 服务器。由服务器连接自己回环地址上的目标服务。
显式写法最前面的 127.0.0.1运行 SSH 客户端的机器。指定本地监听只绑定 IPv4 回环地址。
“本地”是相对于进程运行位置而言

你在哪台机器运行 ssh,哪台就是这一条命令的本地端。如果在另一台机器的远程终端里运行,它的本地入口也在那台机器上;要据此选择应用访问的位置。

省略本地绑定地址时,OpenSSH 默认配置使用回环监听;客户端 GatewayPorts 等配置可能改变行为。需要明确只允许本机使用时,可采用第 6 节的显式绑定写法。配置依据:GatewayPorts。

04 · 一次访问的数据怎样流动

两台机器之间的 SSH 本地端口转发运行 ssh 的机器上,应用连接本地 18080 端口;SSH 客户端通过加密通道把连接送到远端 sshd,再由远端连接自己的 127.0.0.1:8080。响应按相反方向返回。A · 运行 ssh 的机器B · server.example.com浏览器/本地应用连接 127.0.0.1:18080SSH 客户端监听本地端口 18080远端 sshd接收 SSH 连接远端目标服务127.0.0.1:8080本地 TCPSSH 加密通道远端 TCP
箭头表示请求方向;响应沿相反方向返回。图中的账号、域名和端口均为教学示例。
  1. SSH 客户端先与服务器建立 SSH 连接并完成认证,在本地设置转发监听。
  2. 浏览器或其他应用连接运行 ssh 那台机器的 127.0.0.1:18080。
  3. SSH 客户端将这次连接的流量放进 SSH 通道。
  4. 远端收到转发请求后,连接自己的 127.0.0.1:8080,并双向传递数据。

服务连接通常是在有应用访问转发端口时才发起。因此,启动 SSH 时没有报错,不能单独证明目标服务已经可用。

SSH 保护的是客户端与 SSH 服务器之间的通道。应用到本地入口,以及远端 sshd 到目标服务,是各自的连接环节;应用是否还使用 HTTPS 等加密,要看它本身的协议配置。FreeBSD Handbook:SSH Tunneling 介绍了在加密会话中承载其他协议的概念;本图与分步情景为原创说明。

05 · 为什么终端安静?浏览器该怎样访问

-N 不启动远端命令;这条未加 -f 的命令在常见的独立连接方式下留在前台维持转发。认证完成后没有 shell 提示符或持续输出,可以是正常现象。

要使用隧道,可另开浏览器或终端,让应用连接本地入口。停止这条前台 SSH 连接通常可用 Ctrl + C;转发连接结束后,这个入口随之失效。已有连接复用或其他后台转发进程时,应以实际进程与配置为准。

目标服务实际协议本地访问方式需要理解的事
HTTPhttp://127.0.0.1:18080/请求经隧道抵达远端 HTTP 服务。
HTTPShttps://127.0.0.1:18080/TLS 仍由应用与远端服务协商;证书名称和信任仍需匹配。
其他 TCP 应用协议在对应客户端中填写主机 127.0.0.1、端口 18080。不能仅因建立了隧道,就一律使用浏览器访问。

端口号本身不证明协议是什么。转发也不会自动改写应用的重定向地址、Cookie 或证书名称。若服务要求特定主机名或访问入口,还要按该应用的配置处理。

06 · 更明确的写法:显式绑定本地入口

将本地监听地址写完整,并在转发设置失败时退出,可以让启动结果更清楚:

第一个 127.0.0.1 是本地绑定地址;第二个 127.0.0.1 是远端目标地址。位置决定它们属于哪一端。

ExitOnForwardFailure 的验证边界

它用于转发设置失败,例如指定端口无法绑定时终止连接。它不会把后续所有应用连接都变成健康检查,也不会因为最终目标服务连接失败就必然退出。官方配置说明。

Bash
ssh -N \
  -o ExitOnForwardFailure=yes \
  -L 127.0.0.1:18080:127.0.0.1:8080 \
  remote_user@server.example.com

07 · 本地检查:端口监听与应用响应分开看

以下命令由你在运行 SSH 客户端的机器上执行;先确保隧道命令仍在运行。

lsof 示例适用于装有该工具的 macOS/Linux。它用来观察谁在监听本地端口。curl 示例假设目标是 HTTP 服务:-v 显示连接与协议细节,--max-time 10 为一次传输设置时间上限。

观察到的证据可以支持的判断仍然不能证明什么
有对应 SSH 进程监听 127.0.0.1:18080。本地监听入口存在。远端服务一定能连通。
应用收到符合预期的 HTTP 响应。这次请求已获得应用层响应。账号权限、页面功能和长期稳定性都已通过。
应用收到 401/403 或重定向。已有应用层响应,需要继续分析身份、权限或入口配置。不能只凭这些状态判定 SSH 隧道坏了。

若实际服务为 HTTPS,应按实际协议、主机名与证书配置验证。请求是否成功,要结合响应、SSH 诊断信息与目标服务状态一起判断。curl 官方参数说明。

Bash
# Local machine: inspect the listening process.
lsof -nP -iTCP:18080 -sTCP:LISTEN

# Local machine: HTTP example; use the service's actual protocol.
curl -v --max-time 10 http://127.0.0.1:18080/

08 · 远端检查:从正确的一端验证服务

下面这条命令应在SSH 服务器的终端里执行;这里的 127.0.0.1 才对应转发目标那一端。它仍是假设目标使用 HTTP 的示例。

如果远端直接访问目标也失败,应先查目标服务是否监听正确的地址与端口、是否健康。远端直接访问成功而隧道访问失败时,再把本地入口、转发权限与客户端配置纳入排查。

SSH 服务器还可通过 AllowTcpForwarding、PermitOpen 等配置限制转发。成功通过 SSH 认证,与获得指定转发目标的权限,是不同条件;具体限制应由服务器管理方核对。sshd_config(5)。

Bash
# Remote SSH server: verify the target service directly.
# HTTP example; use the service's actual protocol.
curl -v --max-time 10 http://127.0.0.1:8080/

09 · 常见现象:沿证据定位到具体环节

下表文字是排查示例,不是实际环境日志。现象只能缩小范围,不能直接当成根因。

现象或示例提示优先检查判断依据
Address already in use本地监听端口是否已被其他进程占用。先查监听进程,再选择可用的本地端口。
本地应用连接入口时立即被拒绝。SSH 转发进程是否在运行,应用是否连接了正确地址、地址族和本地端口。先确认本地监听事实。
SSH 提示 open failed: connect failed: Connection refused。远端目标地址、端口与服务监听状态。结合远端直接访问结果;拒绝也可能来自网络策略。
SSH 提示 administratively prohibited。服务器与账号的转发限制。核对服务端配置、密钥限制及诊断信息,不能只凭这句话确定是哪条规则。
TCP 已建立,但 HTTP/TLS 报错。协议、证书、主机名、应用认证和重定向。进入应用层后,继续检查该层的预期响应。
开始可用,之后失效。SSH 会话是否中断、网络是否变化、目标服务是否变化。对齐故障时间、SSH 进程与服务日志;一次成功不能证明长期稳定。

需要更多 SSH 连接细节时,可在相同的脱敏命令中增加 -v。对外分享诊断输出前,应检查账号、主机名、IP、密钥路径和应用请求头等内容,并按需要替换或删除。

10 · 复盘:抓住三个端口角色与两端视角

  • 只有连接到本地转发入口的流量才经这条转发传递;其他应用流量不会自动改道。
  • 本地入口端口供本地应用访问;它可以与远端目标端口不同。
  • SSH 连接端口用于建立 SSH 通道,由 -p 或配置决定。
  • 远端目标端口对应真正要访问的服务;本例目标 127.0.0.1 从 SSH 服务器一端解释。

试着回答:如果只想改变浏览器里填写的端口,应修改哪一段?如果远端应用改了监听端口,又应修改哪一段?前者对应示例中的 18080,后者对应 8080。

适用前提

本文按常见的独立 SSH 连接、目标服务位于 SSH 服务器本机来解释。客户端配置可能改变默认连接端口、绑定地址与连接复用行为;可在运行命令的机器上用 ssh -G remote_user@server.example.com 查看最终客户端配置。本文没有验证任何实际服务器的可达性或目标服务状态。

官方资料与内容身份

核验日期:2026-10-15。参数与配置依据来自以下官方资料;示意图、情景、命令中的环境值和分层排查组织为原创教学说明。

SSH本地端口转发TCP网络排查脱敏示例

发布于 2026-10-15。用户名、服务器地址与业务端口均已替换;示例命令和故障文字用于教学,不代表实际环境连接或测试日志。参数依据见文末官方资料。

MORE IN DEVELOPMENT读懂 Python 程序入口:__name__、help() 与 main()