出於安全合規,生產數據庫常禁用公網直連(如關閉 3306 端口、限制來源 IP)。本文詳細講解如何通過 SSH 隧道安全訪問遠程 MySQL,涵蓋 Navicat 圖形化配置、命令行建立隧道、PHP 代碼連接、系統級守護進程化四大場景。
SSH 端口轉發:本地端口 → SSH 加密通道 → 遠程服務器 localhost:3306。客戶端只需連接本地回環地址,流量經 SSH 加密傳輸至數據庫。
| 項目 | 值 |
|---|---|
| 遠程 MySQL IP | 172.21.20.203 |
| MySQL 端口 | 3307 |
| SSH 服務器 IP | 117.123.52.161 |
| SSH 端口 | 79 |
| SSH 用戶 | admin |
| MySQL 用戶/密碼 | test / 123456 |
127.0.0.1,Port 填 3307(或任意本地空閒端口)。


ssh -fNg -L [本地端口]:[遠程DB宿主IP]:[遠程DB端口] [SSH用戶]@[SSH服務器IP] -p [SSH端口]
# 將本地 8989 端口轉發至遠程 172.21.20.203:3307
ssh -fNg -p 79 -L 8989:172.21.20.203:3307 admin@117.123.52.161
參數解析:
-f:後台運行-N:不執行遠程命令,僅轉發端口-g:允許其他主機連接本地轉發端口(可選)-L:本地端口轉發# 連接本地 8989 即等同連接遠程 MySQL
mysql -h 127.0.0.1 -P 8989 -u test -p
<?php
$link = mysqli_connect('127.0.0.1', 'test', '123456', 'dbname', 8989);
// 或 PDO
$pdo = new PDO('mysql:host=127.0.0.1;port=8989;dbname=dbname', 'test', '123456');
?>
應用只需連接本地回環地址與隧道端口,無需感知 SSH 存在。
# 添加一行
ssh_tunnel:345:respawn:/usr/bin/ssh -Ng -L 3307:127.0.0.1:3306 myuser@remotehost.com
# 生效
kill -HUP 1
[Unit]
Description=MySQL SSH Tunnel
After=network.target
[Service]
User=appuser
ExecStart=/usr/bin/ssh -fNg -L 3307:127.0.0.1:3306 myuser@remotehost.com
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
systemctl enable --now mysql-ssh-tunnel
| 現象 | 可能原因 | 解決 |
|---|---|---|
| 連接被拒絕 | SSH 服務器未開啟 AllowTcpForwarding yes | 修改 /etc/ssh/sshd_config 並重啟 sshd |
| 認證失敗 | 密碼/金鑰錯誤、用戶無 Shell 權限 | 檢查 SSH 登錄、改用金鑰認證 |
| 隧道斷開 | 閒置超時、網絡波動 | 配置 ServerAliveInterval 60、用 systemd 守護 |
| 本地端口衝突 | 端口被佔用 | 換空閒端口、netstat -tlnp 排查 |
SSH 隧道是訪問內網 MySQL 的「瑞士軍刀」:開發/運維用 Navicat 最便捷,自動化腳本用命令行,生產應用配置 systemd 守護隧道,PHP 等應用透明連接本地端口。掌握四種姿勢,應對所有訪問受限場景。