SSH 隧道(又称 SSH 端口转发)是 Linux VPS 上最强大的安全技术之一。它能对任意 TCP 流量进行加密、访问未公开的内部服务,并通过服务器创建 SOCKS 代理,无需安装任何额外软件。本指南涵盖所有 SSH 隧道类型,并提供可直接用于生产环境的命令。
什么是 SSH 隧道?为何如此重要?
SSH(安全外壳协议)远不止是一个远程登录工具。其端口转发功能可将任意 TCP 连接封装在加密的 SSH 通道中,并通过 VPS 进行路由。主要优势包括:
- 加密传输 — 默认不加密的服务(MySQL、Redis、普通 HTTP)将通过 SSH 的 AES-256 隧道传输
- 访问封闭服务 — 让数据库绑定在 localhost,通过隧道安全访问,无需对公网暴露端口
- 突破网络限制 — 将 VPS 用作跳板,穿越封锁特定端口的网络
- SOCKS 代理 — 将浏览器或应用程序的流量通过 VPS 所在位置进行路由
- 无需 VPN 软件 — 利用每台 VPS 已运行的 SSH 守护进程即可实现
SSH 隧道的工作原理是:在本地机器与 VPS 之间建立加密通道,然后通过该通道在本地端口与目标端口之间转发数据。传输途中被截获的数据包,在没有私钥的情况下完全无法读取。
SSH 端口转发的三种类型
SSH 支持三种不同的转发模式。了解每种模式的适用场景,可以节省大量排障时间。
| 类型 | 参数 | 方向 | 最适合的场景 |
|---|---|---|---|
| 本地转发 | -L |
本地 → VPS → 目标 | 从本地机器访问 VPS 上的数据库或服务 |
| 远程转发 | -R |
VPS → 本地机器 | 通过 VPS 公网 IP 暴露本地服务 |
| 动态转发 | -D |
本地 SOCKS5 → VPS → 互联网 | 将 VPS 用作浏览器或应用的代理 |
本地端口转发(-L):安全访问 VPS 上的服务
本地端口转发将本地机器某个端口的连接,通过 SSH 连接转发到 VPS(或 VPS 可访问的任意主机)的指定端口。语法如下:
ssh -L [local_port]:[destination_host]:[destination_port] user@vps-ip
最常见的使用场景是安全连接到仅绑定在 VPS localhost 上的 MySQL 数据库,无需对外暴露 3306 端口:
# Create a tunnel: local port 13306 → MySQL on VPS (localhost:3306) ssh -L 13306:localhost:3306 [email protected] -N # Now connect to MySQL through the local port mysql -h 127.0.0.1 -P 13306 -u root -p
-N 参数告知 SSH 不执行远程命令,仅建立隧道。加上 -f 可将进程放到后台运行:
# Background tunnel ssh -f -N -L 13306:localhost:3306 [email protected]
同样的方法适用于 Redis、PostgreSQL 及其他任何服务:
# Tunnel to Redis (port 6379) ssh -L 16379:localhost:6379 [email protected] -N # Tunnel to PostgreSQL (port 5432) ssh -L 15432:localhost:5432 [email protected] -N # Access a private admin panel running on port 8080 of the VPS ssh -L 8888:localhost:8080 [email protected] -N # Open http://localhost:8888 in your browser
本地转发还可以访问 VPS 私有网络中的其他机器:
# Reach an internal server at 192.168.1.100 via the VPS ssh -L 8080:192.168.1.100:80 [email protected] -N
远程端口转发(-R):通过 VPS 暴露本地服务
远程端口转发在 VPS 上开放一个端口,并将连接转发到本地机器。当您希望与远程协作者或 Webhook 端点共享本地笔记本或 NAT 后面的服务时,这非常有用。
ssh -R [vps_port]:[local_host]:[local_port] user@vps-ip
# Open port 8080 on VPS, forwarding to local dev server on port 3000 ssh -R 8080:localhost:3000 [email protected] -N # Anyone who accesses http://203.0.113.10:8080 reaches your local server
默认情况下,SSH 将远程转发端口绑定到 VPS 的 localhost,仅允许 VPS 本机访问。若要允许外部连接,请编辑 VPS 上的 /etc/ssh/sshd_config:
# /etc/ssh/sshd_config on VPS GatewayPorts yes # Reload SSH daemon sudo systemctl reload sshd
若要绑定到 VPS 上的特定网络接口,可在命令中指定绑定地址:
# Bind to all interfaces on VPS ssh -R 0.0.0.0:8080:localhost:3000 [email protected] -N # Bind only to VPS localhost (default behavior without GatewayPorts) ssh -R 127.0.0.1:8080:localhost:3000 [email protected] -N
动态端口转发(-D):通过 VPS 创建 SOCKS5 代理
动态端口转发在本地端口上创建一个 SOCKS5 代理。与本地转发(目标固定为单一地址)不同,动态转发接受任意应用程序发来的 SOCKS 协议请求,并将连接代理到 VPS 可访问的任意目标。
# Create SOCKS5 proxy on local port 1080 ssh -D 1080 [email protected] -N # Run as background process ssh -f -N -D 1080 [email protected]
将应用程序配置为使用 127.0.0.1:1080 的 SOCKS5 代理:
- Firefox:设置 → 网络设置 → 手动代理 → SOCKS5 主机:127.0.0.1 端口:1080
- Chrome:启动时加参数
--proxy-server="socks5://127.0.0.1:1080" - curl:
curl --socks5 127.0.0.1:1080 https://example.com - wget:
wget -e "use_proxy=yes" -e "http_proxy=socks5://127.0.0.1:1080" https://example.com
若要在命令行实现全系统代理,可安装 proxychains:
# Install proxychains sudo apt install proxychains4 # Edit /etc/proxychains4.conf — add: socks5 127.0.0.1 1080 # Use any command through the proxy proxychains4 curl https://api.example.com proxychains4 python3 myscript.py
实用技巧:每条隧道命令都建议加上 -o ServerAliveInterval=60 -o ServerAliveCountMax=3。这会每 60 秒发送一次保活数据包,防止在流量空闲时隧道断开——对于会主动切断空闲 TCP 连接的 VPS 服务商来说尤为重要。
SSH 配置文件:高效管理隧道
每次手动输入冗长的 SSH 命令容易出错。将隧道配置保存到 ~/.ssh/config 中,即可创建便捷的快捷方式:
# ~/.ssh/config
# MySQL tunnel to VPS
Host vps-mysql-tunnel
HostName 203.0.113.10
User ubuntu
IdentityFile ~/.ssh/id_ed25519
LocalForward 13306 localhost:3306
ServerAliveInterval 60
ServerAliveCountMax 3
# SOCKS proxy via VPS
Host vps-socks
HostName 203.0.113.10
User ubuntu
IdentityFile ~/.ssh/id_ed25519
DynamicForward 1080
ServerAliveInterval 60
# Jump Host access to internal server
Host internal-server
HostName 192.168.1.50
User ubuntu
ProxyJump [email protected]
IdentityFile ~/.ssh/id_ed25519
完成配置后,使用方式变得非常简单:
# Open MySQL tunnel ssh -N vps-mysql-tunnel # Start SOCKS proxy ssh -N vps-socks # Connect through jump host directly ssh internal-server
autossh 与 systemd:持久化自动重连隧道
对于需要持续保持连接的隧道,autossh 可监控连接状态,并在断开时自动重连。
# Install autossh
sudo apt update && sudo apt install autossh
# Run a persistent tunnel with autossh
autossh -M 0 -o "ServerAliveInterval=30" -o "ServerAliveCountMax=3" \
-N -L 13306:localhost:3306 [email protected]
-M 0 参数禁用 autossh 自带的监控端口,改为依赖 SSH 内置的保活机制,更加可靠。若要让隧道在重启后自动启动,可将其封装成 systemd 服务:
# /etc/systemd/system/ssh-tunnel-mysql.service
[Unit]
Description=Persistent SSH Tunnel to VPS MySQL
After=network.target
[Service]
User=ubuntu
ExecStart=/usr/bin/autossh -M 0 \
-o "ServerAliveInterval=30" \
-o "ServerAliveCountMax=3" \
-o "ExitOnForwardFailure=yes" \
-N -L 13306:localhost:3306 \
[email protected]
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
# Enable and start the service sudo systemctl daemon-reload sudo systemctl enable ssh-tunnel-mysql sudo systemctl start ssh-tunnel-mysql # Check status sudo systemctl status ssh-tunnel-mysql
该服务开机自动启动,若隧道中断则在 10 秒内自动重启,让您无需对公网开放 MySQL 端口也能随时获得安全的数据库连接。
跳板机(堡垒机):访问私有网络
跳板机(Bastion Host)将 VPS 用作中转节点,访问私有网络中没有公网 IP 的服务器。这种架构仅需在一台服务器上暴露 SSH,大幅缩小攻击面。
# Single command via jump host ssh -J [email protected] [email protected] # Using ProxyCommand (compatible with older SSH versions) ssh -o ProxyCommand="ssh -W %h:%p [email protected]" [email protected]
在 SSH 配置文件中,这一切变得透明无感:
# ~/.ssh/config
Host bastion
HostName 203.0.113.10
User ubuntu
IdentityFile ~/.ssh/id_ed25519
Host db-server
HostName 192.168.1.100
User ubuntu
ProxyJump bastion
Host app-server
HostName 192.168.1.101
User ubuntu
ProxyJump bastion
# SSH handles the jump automatically ssh db-server ssh app-server
使用这种架构,无论添加多少台内网服务器,所有访问都通过唯一的堡垒机流转。这集中了审计日志,简化了防火墙规则——是现代云安全架构的核心理念。
加固 SSH 服务器以保障隧道安全
虽然 SSH 隧道本身已加密,但配置不当的 SSH 服务器仍会带来安全漏洞。请在 VPS 的 /etc/ssh/sshd_config 中应用以下设置:
# Disable password auth — keys only
PasswordAuthentication no
PubkeyAuthentication yes
# Disable direct root login
PermitRootLogin no
# Restrict which users can forward
AllowUsers ubuntu deploy
# Disable X11 if unused
X11Forwarding no
# Use a Match block to allow forwarding per user
Match User ubuntu
AllowTcpForwarding yes
GatewayPorts no
对于仅用于隧道转发、不需要执行 Shell 命令的专用跳板账户:
# Tunnel-only user — no interactive shell
Match User tunnel-user
ForceCommand /bin/false
AllowTcpForwarding yes
X11Forwarding no
PermitTTY no
此外,还应在防火墙层面限制 SSH 访问来源 IP:
# UFW — allow SSH only from your office IP range sudo ufw allow from 203.0.113.0/24 to any port 22 sudo ufw deny 22 # Or move SSH to a non-standard port to avoid automated scanners # In sshd_config: Port 2222 sudo ufw allow 2222/tcp
常见问题解答(FAQ)
SSH 隧道与 VPN 有什么区别?
SSH 隧道仅对您配置的特定端口或应用程序的流量进行加密,适合无需安装额外软件的临时使用场景。VPN 则对本机所有流量通过中央服务器进行加密。如果您已有 VPS 的 SSH 访问权限,SSH 隧道更容易配置;而 VPN 更适合需要路由全部互联网流量的场景。
动态端口转发与本地转发有何不同?
动态端口转发在本地机器上创建 SOCKS5 代理,通过 SSH 将流量路由到 VPS,再转发至任意目标。本地转发只能转发到固定的 host:port。动态转发适合支持 SOCKS 代理的浏览器或应用程序。使用 ssh -D 1080 user@vps-ip,然后在应用程序中将 SOCKS5 代理设置为 localhost:1080。
如何让 SSH 隧道在开机时自动启动?
在 Linux 上结合 autossh 与 systemd 服务实现。创建 /etc/systemd/system/ssh-tunnel.service,其中 ExecStart=/usr/bin/autossh -M 0 -o ServerAliveInterval=30 -N -L 3306:localhost:3306 user@vps-ip。然后运行 systemctl enable ssh-tunnel 和 systemctl start ssh-tunnel,隧道将在开机时自动启动,断开后自动重连。
SSH 隧道足够安全,可以传输敏感数据吗?
SSH 隧道使用基于密钥认证的 AES-256 加密,安全性极高。最佳实践:禁用密码认证(仅使用 SSH 密钥)、仅为授权用户设置 AllowTcpForwarding yes,并通过防火墙规则或 sshd_config 中的 AllowUsers 按 IP 限制访问,防止隧道基础设施被滥用。