什么是 SSH 隧道(端口转发)?本地转发、远程转发、动态转发有什么区别?
简化版
SSH 隧道(端口转发)是借助一条已建立的 SSH 加密连接,把其他 TCP 流量「封装」进去传输,从而实现加密传输 + 穿透防火墙 + 访问原本不可达的资源。它有三种模式:① 本地转发(-L)——把本地某端口的流量,通过 SSH 服务器转发到目标地址,用于「我这边访问不到某服务,但 SSH 服务器能访问到」(如通过跳板机访问内网数据库);② 远程转发(-R)——把 SSH 服务器某端口的流量,反向转发回本地能访问的目标,用于「把我本地的服务暴露给远端」(内网穿透的一种);③ 动态转发(-D)——在本地开一个 SOCKS 代理,所有走这个代理的流量都经 SSH 加密转发出去,相当于一个轻量 VPN/代理。记忆口诀:-L 我去连别人(正向),-R 让别人连我(反向),-D 开个万能代理。
详细版
一、SSH 隧道的本质
SSH 本来是加密远程登录的,但它的加密连接可以顺便承载其他 TCP 流量——把某个端口的数据塞进 SSH 连接,加密传到对端再转发出去。这就是端口转发(Port Forwarding),也叫 SSH 隧道。价值:加密(借 SSH 的加密)+ 穿透(SSH 走 22 端口,常被放行)+ 可达性(借 SSH 服务器的网络位置访问它能到的资源)。
二、三种模式对比
| 模式 | 命令 | 方向 | 用途 |
|---|---|---|---|
| 本地转发 | -L 本地端口:目标:目标端口 | 正向:本地→SSH服务器→目标 | 我访问不到目标,但 SSH 服务器能,借它去访问 |
| 远程转发 | -R 远端端口:目标:目标端口 | 反向:SSH服务器→本地→目标 | 把本地能访问的服务暴露给远端(内网穿透) |
| 动态转发 | -D 本地端口 | 正向 SOCKS 代理 | 本地开 SOCKS 代理,所有流量经 SSH 加密转发 |
三、本地转发 -L(最常用)
ssh -L 3306:db.internal:3306 user@jump-server
含义:访问我本地的 3306 → 经 jump-server → 转发到 db.internal:3306。
场景:数据库 db.internal 只在内网、我直连不到,但跳板机 jump-server 能连它。于是我在本地连 localhost:3306,流量经 SSH 加密到跳板机,再由跳板机去连数据库。我借跳板机的位置访问了内网资源。
四、远程转发 -R(反向暴露)
ssh -R 8080:localhost:80 user@public-server
含义:访问 public-server 的 8080 → 反向经 SSH 回到我本地 → 转发到我的 localhost:80。
场景:我本地跑了个 web 服务(localhost:80),想让外网访问,但我在 NAT 后没公网 IP。于是我主动 SSH 连到有公网 IP 的 public-server,把它的 8080 反向映射到我本地的 80。外网访问 public-server:8080 就能到我本地服务——这就是 SSH 版内网穿透。
五、动态转发 -D(SOCKS 代理)
ssh -D 1080 user@ssh-server
含义:本地开一个 SOCKS5 代理(1080 端口)。任何配置走 localhost:1080 代理的应用,流量都会经 SSH 加密转发,从 ssh-server 出口。相当于一个轻量级 VPN/代理,不用为每个目标单独配 -L。
完整版教学
一、为什么 SSH 能当隧道用
SSH 的本职是加密的远程登录/命令执行。但 SSH 协议里有个「通道(channel)」机制,一条 SSH 连接上可以复用多个逻辑通道。除了跑登录 shell,它也能承载任意 TCP 流量——把某个端口收到的数据,通过 SSH 加密连接送到对端,再由对端转发到真正的目标。
于是 SSH 隧道给你三样东西:
- 加密:流量搭 SSH 的加密连接,天然被加密保护。
- 穿透:SSH 走 22 端口(或自定义端口),很多防火墙放行;把其他流量藏进 SSH,就能借道穿过。
- 可达性借用:SSH 服务器能访问的资源,你就能通过隧道间接访问(跳板机模式)。
理解这三点,三种转发模式就都是「往哪个方向借道」的变体。
二、本地转发 -L:我主动去连(正向)
语法:ssh -L [本地监听地址:]本地端口:目标主机:目标端口 user@ssh服务器
数据流向:
你的应用 → localhost:本地端口
→ (SSH 加密隧道)→ ssh服务器
→ ssh服务器再去连 目标主机:目标端口
注意:「目标主机:目标端口」是从 SSH 服务器的视角去解析和连接的。所以本地转发的适用场景是:你直连不到目标,但 SSH 服务器能连到目标。
经典场景——跳板机访问内网数据库:
ssh -L 3306:db.internal:3306 user@jump-server
# 然后本地:mysql -h 127.0.0.1 -P 3306
你连不到内网的 db.internal,但跳板机 jump-server 在内网、连得到。本地转发让你连本地 3306,流量加密送到跳板机,跳板机替你去连数据库。你「借」了跳板机的网络位置。
三、远程转发 -R:让别人来连我(反向)
语法:ssh -R [远端监听地址:]远端端口:目标主机:目标端口 user@ssh服务器
数据流向(和 -L 相反):
别人 → ssh服务器:远端端口
→ (SSH 隧道反向)→ 你的本机
→ 你的本机再去连 目标主机:目标端口(通常是 localhost)
注意:监听端口开在 SSH 服务器上,流量反向送回你这边,「目标主机」是从你本机视角去连的。适用场景:把你本地/你能访问的服务,暴露给 SSH 服务器那一侧的人。
经典场景——把内网服务暴露到公网(SSH 版内网穿透):
ssh -R 8080:localhost:80 user@public-server
你在 NAT 后、没公网 IP,本地跑着 web:80。你主动连有公网 IP 的 public-server,把它的 8080 反向映射回你本地 80。外网访问 public-server:8080,就穿过隧道到了你本地服务。这正体现了内网穿透「内网主动出去建连、外部流量反向进来」的思路。
提示:让
-R监听在公网服务器的外部地址(而非仅 localhost),需要服务器sshd_config里GatewayPorts yes。
四、动态转发 -D:一个万能 SOCKS 代理
-L/-R 都要为每个目标写死地址。如果你想「所有流量都经 SSH 出去、目标不定」,就用动态转发:
语法:ssh -D [本地地址:]本地端口 user@ssh服务器
它在本地开一个 SOCKS 代理(通常 SOCKS5)。应用只要把代理设成 localhost:该端口,发起的连接会经 SSH 隧道加密、从 SSH 服务器出口再去连各自的目标。目标是应用动态告诉 SOCKS 代理的,不用预先固定。
ssh -D 1080 user@ssh-server
# 浏览器/应用配置 SOCKS5 代理 127.0.0.1:1080
效果类似一个轻量 VPN / 加密代理:流量加密、从 ssh-server 的网络位置出口。适合「用一台可信服务器做统一加密出口」的场景。
五、三者一张图对照
-L 本地转发(正向,我去连别人):
[本地应用] → localhost:L端口 →SSH→ [SSH服务器] → 目标:端口
-R 远程转发(反向,别人来连我):
[远端的人] → SSH服务器:R端口 →SSH→ [我本地] → 目标(通常localhost):端口
-D 动态转发(正向 SOCKS 代理,谁都能连、目标不定):
[本地应用] → localhost:D端口(SOCKS) →SSH→ [SSH服务器] → 应用指定的任意目标
- 谁监听:
-L/-D监听在本地,-R监听在SSH 服务器。 - 谁去连目标:
-L/-D由SSH 服务器去连目标,-R由本地去连目标。 - 方向感:
-L出(我借道出去访问),-R入(把我暴露给别人)。
六、常见用途与优点
- 跳板机 / 堡垒机访问内网(
-L):安全运维的标配。 - 临时暴露本地服务给外网(
-R):调试、演示、临时内网穿透。 - 加密出口 / 绕过网络限制(
-D):把流量统一走可信服务器加密出口。 - 优点:几乎零部署(有 SSH 就行)、天然加密、走 22 端口易穿防火墙。
- 局限:基于 TCP(UDP 不能直接转,需额外手段),性能一般,不适合大流量长期承载,重场景还是用正规 VPN。
七、常见误区与追问
| 考点 | 正确口径 |
|---|---|
| 本地转发 | 访问本地端口,经 SSH 到远端访问目标 |
| 远程转发 | 远端开放端口,流量经 SSH 回到本地 |
| 动态转发 | 本地 SOCKS 代理,经 SSH 转发多目标 |
local: ssh -L 8080:db.internal:5432 user@bastion
remote: ssh -R 9000:localhost:3000 user@server
dynamic:ssh -D 1080 user@bastion
SSH 隧道本质是把 TCP 流量塞进 SSH 加密连接里,方向由 -L、-R、-D 决定。
- 误区:SSH 隧道就是 VPN。 SSH 隧道通常转发端口或 SOCKS 流量,不一定接入整个三层网络。
- 误区:本地转发和远程转发方向一样。 -L 是本地监听转到远端可达目标,-R 是远端监听转回本地可达目标。
- 误区:SSH 隧道不需要权限控制。 隧道可能绕过网络边界,必须限制账号、目标、来源和审计。
- 追问:动态转发适合什么? 适合临时代理多目标访问,本地程序通过 SOCKS5 走 SSH 出口。
- 追问:堡垒机里为什么常用本地转发? 开发机不能直连内网数据库,但堡垒机可达,通过 -L 安全转发。
- 追问:如何降低隧道风险? 禁用不必要的 AllowTcpForwarding,限制 PermitOpen,使用强认证和日志审计。
八、加强记忆
SSH 隧道(端口转发)= 借一条 SSH 加密连接承载其他 TCP 流量,获得加密 + 穿透防火墙(走 22)+ 借用 SSH 服务器的可达性。三种模式:-L 本地转发(正向,监听在本地,SSH 服务器替我去连目标)——我访问不到、借跳板机去访问内网资源;-R 远程转发(反向,监听在 SSH 服务器,流量回到我本地)——把我本地服务暴露给远端,SSH 版内网穿透;-D 动态转发(本地开 SOCKS 代理,目标不定、统一加密出口)——轻量 VPN/代理。口诀:-L 我去连别人,-R 让别人连我,-D 开个万能代理。 它只转 TCP、性能一般,重场景用正规 VPN。