如何通过 SSH 隧道访问远程数据库?
数据库在内网不能直接访问,需要通过跳板机/SSH 隧道连接远程 MySQL/PostgreSQL/Redis
解决方案
本地端口转发访问远程数据库(推荐) 推荐
# MySQL(远程 3306 → 本地 3307) ssh -fNL 3307:localhost:3306 user@db-server mysql -h 127.0.0.1 -P 3307 -u dbuser -p # PostgreSQL(远程 5432 → 本地 5433) ssh -fNL 5433:localhost:5432 user@db-server psql -h 127.0.0.1 -p 5433 -U dbuser -d mydb # Redis(远程 6379 → 本地 6380) ssh -fNL 6380:localhost:6379 user@db-server redis-cli -h 127.0.0.1 -p 6380
-f 后台运行,-N 不开 shell,-L 本地端口:目标:目标端口。隧道建立后,用本地客户端连接 127.0.0.1:本地端口即可。这里 localhost 是相对于 SSH 服务器的。
适用场景:数据库和 SSH 服务器在同一台机器上,或 SSH 服务器可以直接访问数据库
通过跳板机访问内网数据库
# 数据库在内网 db.internal:3306,通过跳板机 bastion 访问 ssh -fNL 3307:db.internal:3306 user@bastion mysql -h 127.0.0.1 -P 3307 -u dbuser -p # 或在 ~/.ssh/config 中配置 # Host db-tunnel # HostName bastion.example.com # User jump-user # LocalForward 3307 db.internal:3306 # LocalForward 5433 pg.internal:5432 # 然后直接:ssh -fN db-tunnel
当数据库不在 SSH 服务器本机时,目标地址填数据库的内网地址。SSH 服务器作为中转,将流量转发到内网数据库。
适用场景:数据库在内网,需要通过跳板机/堡垒机中转访问
使用 autossh 保持隧道稳定
# 安装 autossh sudo apt install autossh # Debian/Ubuntu brew install autossh # macOS # 使用 autossh 建立自动重连的隧道 autossh -M 0 -fNL 3307:localhost:3306 user@db-server \ -o ServerAliveInterval=30 \ -o ServerAliveCountMax=3 # 配合 systemd 开机自启 # /etc/systemd/system/ssh-tunnel-db.service # [Unit] # Description=SSH Tunnel to DB # After=network.target # [Service] # ExecStart=/usr/bin/autossh -M 0 -NL 3307:localhost:3306 user@db-server # Restart=always # [Install] # WantedBy=multi-user.target
autossh 监控 SSH 连接状态,断开后自动重连。-M 0 表示使用 SSH 自身的心跳机制检测连接状态。配合 systemd 可以实现开机自启和崩溃重启。
适用场景:需要长期稳定的数据库隧道,不能容忍连接中断
注意事项
隧道断开后本地连接也会断开,生产环境建议用 autossh 或 systemd 保活
不要在本地端口使用和远程相同的端口号,避免与本地服务冲突
确保 SSH 服务器允许 TCP 转发(AllowTcpForwarding yes)