SSH隧道通过加密通道连接本地客户端与远程数据库服务器,在公网上安全传输数据,有效防止敏感信息泄露,是建立安全数据库连接的可靠桥梁。
直接使用 ssh
命令本身并不能像 mysql
或 psql
那样直接操作数据库,它的核心作用是建立一个加密的安全通道(SSH隧道),让你能够通过这个通道,安全地访问位于远程服务器(通常是受保护的内网环境)上的数据库服务,这是连接生产环境或私有网络数据库的标准且安全的方法。
为什么需要 SSH 隧道?
- 安全性:
- 数据库服务(如 MySQL 的 3306 端口、PostgreSQL 的 5432 端口)直接暴露在公网上是极其危险的,容易遭受暴力破解和攻击。
- SSH 使用强加密算法(如 AES)保护传输的所有数据,包括你的数据库用户名和密码。
- SSH 提供强大的身份验证机制(密码或更安全的密钥对)。
- 绕过防火墙限制:
- 数据库服务器通常配置了防火墙,只允许来自特定内部网络或特定IP(如应用服务器)的连接,拒绝来自公网的直接访问。
- SSH 服务(端口 22)通常是服务器上唯一对外开放且严格管理的端口,通过 SSH 隧道,你可以“借道”这个开放的 SSH 端口来访问内部数据库。
- 访问私有网络资源:
数据库可能部署在私有子网(如云环境的 VPC 内网)中,外部根本无法直接路由到,你需要先通过 SSH 连接到一台可以访问该私有网络的“跳板机”(Bastion Host),然后通过这台跳板机建立隧道访问数据库。
如何建立 SSH 隧道连接数据库?
你需要使用 SSH 的端口转发功能,具体是 本地端口转发 (-L
),原理是:
- 在你的本地机器上选择一个未被使用的端口(
63306
)。 - 通过 SSH 连接到可以访问目标数据库的远程服务器(跳板机)。
- 告诉 SSH:“请把我本地
63306
端口的所有连接请求,通过这个 SSH 加密通道,转发到目标数据库服务器(可能是跳板机自身,也可能是另一台内网机器)的数据库端口(如3306
)上。” - 你的本地数据库客户端(如 MySQL Workbench, DBeaver,
mysql
命令行,psql
命令行等)不再直接连接远程数据库,而是连接到你本地的63306
端口。 - SSH 客户端会将这个本地端口上的流量,通过加密的 SSH 连接,安全地转发到远程数据库服务器的实际端口上。
具体命令格式:
ssh -L [本地绑定IP:]本地端口:目标数据库主机:目标数据库端口 用户名@跳板机主机名或IP [-p 跳板机SSH端口]
参数详解:
-L
: 指定进行本地端口转发。[本地绑定IP:]
: (可选) 指定本地哪个网络接口监听这个端口,通常省略(表示0.0.1
或localhost
),这样只有你本机的应用能连接,最安全,如果需要本机其他IP或网络访问,需明确指定(有安全风险,慎用)。本地端口
: 你在本地机器上打开的端口(如63306
,65432
),选择一个大于 1024 且未被占用的端口。目标数据库主机
: 数据库实际运行的主机名或IP地址,这可以是:- 跳板机自身 (
localhost
或0.0.1
),如果数据库就安装在跳板机上。 - 跳板机所在内网的另一台机器的私有IP (如
0.0.5
,168.1.100
),如果数据库在另一台机器上。
- 跳板机自身 (
目标数据库端口
: 数据库服务监听的端口(MySQL: 3306, PostgreSQL: 5432, Redis: 6379, MongoDB: 27017 等)。用户名@跳板机主机名或IP
: 你用于登录跳板机的 SSH 用户名和跳板机的公网主机名或IP地址。-p 跳板机SSH端口
: (可选) 如果跳板机的 SSH 服务不是默认的 22 端口,需要用此参数指定。
连接步骤示例:
场景 1:数据库安装在跳板机上 (最常见)
- 目标:通过跳板机
bastion.yourcompany.com
(SSH 用户youruser
) 连接其本机上运行的 MySQL 数据库 (端口 3306)。 - 本地打开端口:
63306
- 命令:
ssh -L 63306:localhost:3306 youruser@bastion.yourcompany.com
- 解释: 连接
bastion.yourcompany.com
,将你本地63306
端口的流量,通过 SSH 隧道,转发到跳板机自身 (localhost
) 的3306
端口(即 MySQL)。 - 使用: 打开你的 MySQL 客户端,连接
主机名: 127.0.0.1 或 localhost
,端口: 63306
,然后输入数据库的用户名和密码(数据库自身的认证信息,不是SSH的!)。
场景 2:数据库在内网另一台机器上
- 目标:通过跳板机
jumpbox.cloud.com
(SSH 用户jumpuser
) 连接内网机器db-internal.private
(IP1.2.3
) 上的 PostgreSQL 数据库 (端口 5432)。 - 本地打开端口:
65432
- 命令:
ssh -L 65432:10.1.2.3:5432 jumpuser@jumpbox.cloud.com
- 解释: 连接
jumpbox.cloud.com
,将你本地65432
端口的流量,通过 SSH 隧道和跳板机,转发到内网主机1.2.3
的5432
端口(即 PostgreSQL)。 - 使用: 打开你的 PostgreSQL 客户端 (如
psql
),连接主机名: localhost
,端口: 65432
,然后输入数据库的用户名和密码。
场景 3:使用非标准SSH端口
- 跳板机
gateway.example.com
的 SSH 端口是2222
,数据库在其本机运行 MySQL。 - 命令:
ssh -L 63306:localhost:3306 -p 2222 youruser@gateway.example.com
重要提示与最佳实践 (体现E-A-T):
- 身份验证:
- 优先使用 SSH 密钥对: 密码登录易受暴力破解,使用
ssh-keygen
生成密钥对,将公钥 (id_rsa.pub
) 添加到跳板机用户的~/.ssh/authorized_keys
文件中,连接时通常无需输入密码,更安全便捷,命令本身不需要变,SSH 会自动尝试使用密钥。 - 强密码: 如果必须用密码,确保是强密码。
- 优先使用 SSH 密钥对: 密码登录易受暴力破解,使用
- 最小权限原则: 用于连接跳板机的 SSH 用户应仅拥有建立隧道所需的最低权限,不应是
root
或具有数据库高权限的账户。 - 本地端口选择: 使用高位端口 (大于 1024),避免与系统服务冲突,确保该端口在本地未被占用 (
netstat -an | grep LISTEN | grep <端口号>
或lsof -i :<端口号>
检查)。 - 保持隧道连接: 执行上述
ssh -L
命令后,终端窗口会保持打开状态以维持 SSH 连接和隧道,关闭此窗口或按Ctrl+C
会断开 SSH 并终止隧道,此时你的数据库客户端连接也会中断。- 后台运行 (
-f -N
): 如果你不想占用终端,可以添加-f
(后台运行) 和-N
(不执行远程命令) 参数:ssh -f -N -L 63306:localhost:3306 youruser@bastion.yourcompany.com
关闭隧道需要用
ps
找到进程ID或用pkill -f "ssh -L 63306"
(谨慎使用)。
- 后台运行 (
- 数据库客户端配置: 在数据库客户端软件中,主机名/地址始终填写
0.0.1
或localhost
,端口填写你-L
参数中指定的本地端口
,数据库的用户名和密码是目标数据库自身的认证凭据,与 SSH 的用户名密码无关。 - 防火墙: 确保跳板机的防火墙允许你的本地 IP 连接到其 SSH 端口 (通常是 22),确保跳板机到目标数据库主机(如果是内网另一台)的防火墙允许跳板机访问目标数据库端口。
- 连接问题排查:
- SSH 连接失败: 检查跳板机地址、SSH端口、用户名、密钥/密码是否正确;检查本地网络和跳板机状态;检查跳板机防火墙。
- 隧道建立但数据库连不上: 检查
-L
参数中的目标数据库主机
和目标数据库端口
是否正确;检查目标数据库是否在运行 (netstat -tuln | grep <端口>
在目标数据库主机上);检查目标数据库是否监听0.0.0
或对应IP(不是0.0.1
);检查目标数据库主机的防火墙规则;检查数据库用户是否有从localhost
(如果目标主机是localhost
) 或跳板机IP (如果目标是内网IP) 连接的权限 (GRANT
语句)。 - 超时/中断: 检查网络稳定性;检查 SSH 服务端和客户端的超时设置;避免长时间空闲(可配置
ServerAliveInterval
和ServerAliveCountMax
)。
- 安全警告:
- 不要暴露数据库端口到公网: SSH 隧道的核心价值就是避免这样做。
- 保护 SSH 密钥: 私钥文件 (
id_rsa
) 是你的数字身份,务必妥善保管,设置强密码保护密钥文件本身 (ssh-keygen -p
),不要泄露。 - 谨慎使用
0.0.0
绑定:-L 0.0.0.0:63306:localhost:3306 ...
会让本地所有网络接口监听 63306 端口,可能被同一网络的其他机器访问,带来风险,仅在明确需要且理解风险时使用。
使用 ssh -L
命令建立本地端口转发隧道,是安全连接远程或受保护网络内数据库服务的标准方法,其本质是通过加密的 SSH 连接,将本地一个端口的流量安全地“映射”到目标数据库服务器的端口上,配置时务必注意目标主机地址、端口、跳板机信息以及最重要的安全实践(密钥认证、最小权限、防火墙),配置好隧道后,你的数据库客户端只需像连接本地数据库一样连接 localhost:本地端口
即可安全访问远程资源。
引用说明:
- 本文所述 SSH 端口转发功能基于 OpenSSH 实现,其官方文档是权威参考: https://www.openssh.com/manual.html (查找
ssh
命令手册页,特别是-L
选项部分)。 - 具体数据库(MySQL, PostgreSQL, MongoDB等)的连接细节、端口号及安全配置,请务必参考相应数据库的官方文档。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/7729.html