4、SSH隧道技术:SSH本地端口转发、SSH远程端口转发、SSH动态端口转发(SOCKS代理)、实战:通过SSH访问内网服务器

SSH 隧道,说白了就是一条加密的「数据管道」。你想想看,内网服务器没有公网 IP,外面的人怎么连?SSH 隧道就是解决这个问题的。我做了这么多年运维,遇到远程访问的场景,第一个想到的往往就是 SSH 隧道——因为它简单、安全,而且几乎所有 Linux 系统都自带。

这一章我们重点讲三种隧道模式:本地转发、远程转发、动态转发。每种模式都有它的适用场景,搞懂了它们,你就能灵活地穿透各种网络限制。

4.1 SSH本地端口转发(Local Forwarding)

本地转发,就是把远程机器的某个端口,映射到你本地的某个端口上。访问本地端口,就等于访问远程端口。

举个例子:你本地电脑想访问公司内网的一台数据库服务器(比如 MySQL,端口 3306),但数据库服务器没有公网 IP,只有一台跳板机(堡垒机)有公网 IP。这时候就可以用本地转发。

命令格式:

ssh -L [本地IP:]本地端口:目标IP:目标端口 跳板机用户@跳板机IP

实战命令:

ssh -L 3307:内网数据库IP:3306 跳板机用户@跳板机公网IP

执行后,你本地电脑的 3307 端口,就通过跳板机加密隧道,连接到了内网数据库的 3306 端口。你只需要在本地用 mysql -h 127.0.0.1 -P 3307 就能连上内网数据库。

我的经验:本地转发适合「从外向内」访问的场景。我曾经帮客户排查一个数据库连接问题,他们用 VPN 连内网,速度慢得要命。我建议改用 SSH 本地转发,直接在本地开一个端口映射到内网数据库,速度提升了好几倍。而且 SSH 的加密开销比 VPN 小得多。

4.2 SSH远程端口转发(Remote Forwarding)

远程转发正好反过来——把本地机器的某个端口,映射到远程机器的某个端口上。访问远程机器的端口,就等于访问本地端口。

这个模式特别适合「内网机器主动向外暴露服务」的场景。比如你有一台内网服务器,没有公网 IP,但你需要从外网访问它上面的 Web 服务(端口 8080)。这时候可以让内网服务器主动连接一台有公网 IP 的中转服务器,建立远程转发。

命令格式:

ssh -R [远程IP:]远程端口:本地IP:本地端口 中转服务器用户@中转服务器IP

实战命令(在内网服务器上执行):

ssh -R 8080:localhost:8080 中转用户@中转公网IP

执行后,你访问中转服务器的 8080 端口,流量就会通过 SSH 隧道转发到内网服务器的 8080 端口。

注意:远程转发需要中转服务器的 SSH 配置中开启 GatewayPorts yes,否则默认只监听在 127.0.0.1 上,外部无法访问。我曾经踩过这个坑,配置好转发后怎么都连不上,排查了半天才发现是 GatewayPorts 没开。

4.3 SSH动态端口转发(SOCKS代理)

动态转发,就是建立一个 SOCKS 代理。它不像前两种那样固定映射某个端口,而是让你本地电脑通过这个代理,动态地访问远程网络中的任意主机和端口。

命令格式:

ssh -D [本地IP:]本地SOCKS端口 跳板机用户@跳板机IP

实战命令:

ssh -D 1080 跳板机用户@跳板机公网IP

执行后,你本地电脑的 1080 端口就变成了一个 SOCKS5 代理。你在浏览器或系统网络设置中配置这个代理,所有流量就会通过 SSH 隧道,从跳板机发出。这样你就能访问跳板机所在内网的所有资源了。

核心区别:
  • 本地转发:固定映射一个远程端口到本地
  • 远程转发:固定映射一个本地端口到远程
  • 动态转发:建立一个 SOCKS 代理,灵活访问远程网络

4.4 三种转发模式对比

转发类型 方向 典型场景 命令参数
本地转发 外 → 内 从外网访问内网数据库、Web 服务 -L
远程转发 内 → 外 内网服务器主动暴露服务到外网 -R
动态转发 外 → 内(灵活) 通过 SOCKS 代理访问内网任意资源 -D

4.5 实战:通过SSH访问内网服务器

我们用一个完整的实战案例,把三种转发串起来。假设场景如下:

  • 你有一台公网跳板机(IP: 203.0.113.10)
  • 内网有一台 Web 服务器(IP: 192.168.1.100,端口 80)
  • 内网有一台数据库服务器(IP: 192.168.1.200,端口 3306)
  • 你本地电脑需要同时访问这两台内网服务器

方案一:本地转发(访问 Web 服务器)

ssh -L 8080:192.168.1.100:80 用户@203.0.113.10

然后浏览器访问 http://127.0.0.1:8080 即可。

方案二:本地转发(访问数据库服务器)

ssh -L 3307:192.168.1.200:3306 用户@203.0.113.10

然后本地用 mysql -h 127.0.0.1 -P 3307 连接。

方案三:动态转发(同时访问所有内网资源)

ssh -D 1080 用户@203.0.113.10

然后在浏览器设置 SOCKS5 代理为 127.0.0.1:1080,就可以直接访问 http://192.168.1.100 和 mysql -h 192.168.1.200 了。

我的建议:如果只需要访问一两个固定服务,用本地转发更简单直接。如果需要频繁访问内网的不同服务,动态转发更灵活。我个人习惯在笔记本上常驻一个动态转发隧道,配合浏览器 SwitchyOmega 插件,需要时一键切换代理,非常方便。

4.6 SSH隧道核心逻辑图

下面这张图展示了三种 SSH 隧道的工作逻辑:

SSH 隧道三种转发模式核心逻辑 本地转发 (-L) 本地端口 → 远程目标端口 本地电脑 跳板机 内网目标 远程转发 (-R) 远程端口 → 本地目标端口 内网服务器 中转服务器 外网用户 动态转发 (-D) SOCKS 代理,灵活访问 本地电脑 跳板机 内网任意服务 说明: 实线箭头表示 SSH 连接建立方向,虚线箭头表示数据流转方向。三种模式本质都是通过 SSH 加密隧道转发 TCP 流量。

4.7 避坑指南

  • 连接断开问题:SSH 隧道默认没有保活机制,长时间空闲可能会断开。建议加上 -o ServerAliveInterval=60 参数,每 60 秒发一次心跳包。
  • 端口冲突:本地端口不要被其他程序占用。我习惯用 3307、8080、1080 这些不常用的端口。
  • 权限问题:如果使用 1024 以下的特权端口(比如 80、443),需要 root 权限。建议用高端口,然后用 iptables 或 nginx 转发。
  • 多隧道管理:如果同时开多个隧道,建议用 ~/.ssh/config 配置文件管理,或者用 autossh 工具自动重连。
安全提醒:SSH 隧道虽然加密,但跳板机本身的安全很重要。如果跳板机被攻破,隧道里的流量就可能被窃听。建议跳板机开启双因素认证,并限制 SSH 登录 IP。

好了,SSH 隧道的三种模式就讲到这里。本地转发、远程转发、动态转发,每种都有它的用武之地。你只要记住一个原则:谁主动发起连接,谁就执行 SSH 命令。本地转发是你在本地执行,远程转发是内网机器执行,动态转发是你在本地执行但代理到远程网络。搞清楚了这一点,SSH 隧道就没什么难的了。