SSH 隧道
SSH 端口转发(隧道)是一种利用 SSH 连接来加密和重定向网络流量到远程或本地端口的技术。主要有两种类型:本地端口转发(Local Forwarding,也称"本地隧道")和远程端口转发(Remote Forwarding,也称"远程隧道")。下面详细介绍它们的指令格式、工作原理和常用选项。
1. SSH 本地端口转发(-L)
指令格式
ssh -L [本地地址:]本地端口:目标地址:目标端口 用户@SSH服务器
- 本地地址:可选,默认为
localhost,表示只允许本机连接。若设为0.0.0.0或省略本地地址部分(但写为*:在某些系统上),则允许其他机器通过该 SSH 客户端转发。 - 本地端口:在 SSH 客户端机器上监听的端口。
- 目标地址:目标端口:最终要访问的目标主机和端口。这个目标是从 SSH 服务器 的角度能够访问到的地址(可以是远程主机,也可以是 SSH 服务器自身)。
- 用户@SSH服务器:作为跳板机的 SSH 服务器登录信息。
工作原理
- 客户端在本地开启一个监听端口。
- 任何连接到此本地端口的流量,都会被 SSH 客户端加密后发送到 SSH 服务器。
- SSH 服务器解密后,再将数据转发到指定的目标地址:目标端口。
- 目标服务器的响应原路返回。
形象理解:你通过 SSH 连接到一台公网服务器,让这台服务器帮你访问内部网络的服务(比如数据库),并把数据传回给你。
示例
# 将本地的 8080 端口转发到目标服务器 www.example.com 的 80 端口(通过跳板机 ssh.example.com)
ssh -L 8080:www.example.com:80 user@ssh.example.com
# 访问本地的 8080 端口,实际上就是访问 www.example.com:80
# 浏览器中打开 http://localhost:8080
更常见的情况:访问内网机器 如果你的跳板机可以访问内网的一台机器(如 192.168.1.100),你想从本机访问该机器的 3306 端口:
ssh -L 3306:192.168.1.100:3306 user@ssh.example.com
此时连接本机 3306 端口相当于连接内网 192.168.1.100:3306。
2. SSH 远程端口转发(-R)
指令格式
ssh -R [远程地址:]远程端口:目标地址:目标端口 用户@SSH服务器
- 远程地址:可选,默认为
localhost,表示 SSH 服务器只允许自己连接该转发端口。若设为0.0.0.0,则需要 SSH 服务器开启GatewayPorts选项,允许远程主机连接。 - 远程端口:在 SSH 服务器 上监听的端口。
- 目标地址:目标端口:最终要访问的目标主机和端口。这个目标是从 SSH 客户端 的角度能够访问到的地址(通常是客户端所在内网的服务)。
- 用户@SSH服务器:作为公网跳板机的 SSH 服务器。
工作原理
- SSH 服务器(远程主机)上开启一个监听端口。
- 任何连接到此远程端口的流量,都会被 SSH 服务器加密后发送给 SSH 客户端。
- SSH 客户端解密后,再将数据转发到指定的目标地址:目标端口(通常是客户端内网的服务)。
- 目标服务器的响应原路返回。
形象理解:你有一台内网机器(没有公网 IP),通过 SSH 连接到一台有公网 IP 的服务器,并告诉公网服务器:"你在端口 8080 上收到的请求,都转发给我,我会帮你访问我的内网某服务,并把结果返回给你。"这样公网用户就可以通过公网服务器的端口访问你的内网服务。
示例
假设你有一台内网机器(IP 192.168.1.10),它上面运行着一个 Web 服务(端口 80),你想让外网的人通过你的公网服务器(ssh.example.com)访问这个服务。
在内网机器上执行:
ssh -R 8080:localhost:80 user@ssh.example.com
这样在公网服务器 ssh.example.com 上就会监听 8080 端口(默认只监听 127.0.0.1)。然后外网用户需要先登录到 ssh.example.com,再通过 curl http://localhost:8080 来访问。如果希望外网用户能直接访问,需要公网服务器的 SSH 配置中开启 GatewayPorts yes,并将远程地址设为 0.0.0.0:
ssh -R 0.0.0.0:8080:localhost:80 user@ssh.example.com
此时外网用户就可以通过 http://ssh.example.com:8080 访问你的内网 Web 服务了。
3. 常用选项
- -N:不执行远程命令,只建立端口转发(不分配伪终端)。通常用于只做隧道的情况。
- -f:后台运行 SSH(要求已经配置好密钥或自动登录)。
- -g:允许远程主机(在 -L 场景中)连接到本地转发端口(即允许非本机的客户端连接本地监听的端口)。相当于将本地地址隐式设为
0.0.0.0。 - -v:详细输出,用于调试。
典型组合:
ssh -fN -L 8080:www.example.com:80 user@ssh.example.com
4. 动态转发(补充)
除了本地和远程转发,还有动态转发(-D),它创建一个 SOCKS 代理,可以动态转发任意目标:
ssh -D 1080 user@ssh.example.com
然后在浏览器等应用中设置 SOCKS 代理为 localhost:1080,所有流量都会通过 SSH 服务器转发。
5. 注意事项
- 权限:监听低于 1024 的端口通常需要 root 权限。
- GatewayPorts:远程转发默认只监听 SSH 服务器的 loopback 地址,若需要外部访问,需在服务器 SSH 配置文件
/etc/ssh/sshd_config中设置GatewayPorts yes并重启 sshd。 - 防火墙:确保 SSH 服务器上的防火墙允许相应端口的入站连接。
- 稳定性:长期隧道可配合
autossh工具,自动重连。 - 安全性:端口转发可能带来安全风险,应仅在信任的环境中使用。