| 參數 | 含義 |
| -f | 認證後背景執行 (需配合 -N) |
| -N | 不執行遠端 Shell/命令,純轉發 |
| -g | 允許遠端主機連線本地轉發埠 (GatewayPorts),預設僅 127.0.0.1 |
| -L local:target:port | 本地轉發:本地 IP:埠 → 目標主機:埠 (目標主機從 SSH Server 視角) |
| -R remote:local:port | 遠端轉發:遠端 IP:埠 → 本地主機:埠 |
| -p PORT | 指定 SSH 伺服器埠 (非預設 22) |
| -i KEY_FILE | 指定私鑰檔案 (免密登入) |
| -o ServerAliveInterval=60 | 保持連線心跳,防斷開 |
| -o ExitOnForwardFailure=yes | 轉發失敗即退出,便於腳本檢測 |
實戰範例:跳板機架構
拓撲:開發機 (Windows) → 跳板機 117.123.52.161:79 → MySQL 172.21.20.203:3307
1. 命令列建立隧道
ssh -fNg -p 79 -L 8989:172.21.20.203:3307 admin@117.123.52.161
# 本地 8989 → 跳板機視角的 172.21.20.203:3307
2. 本地客戶端連線驗證
# 命令列
mysql -h 127.0.0.1 -P 8989 -u dbuser -p dbname
# PHP
$pdo = new PDO("mysql:host=127.0.0.1;port=8989;dbname=dbname;charset=utf8mb4", "dbuser", "pass");
# Navicat / Workbench / DBeaver
# Host: 127.0.0.1, Port: 8989

3. Navicat 內建 SSH 隧道 (免命令列)
- 連線設定 → SSH 分頁 → 勾選「使用 SSH 隧道」
- SSH Host: 117.123.52.161, Port: 79
- SSH User: admin, Password/Key: 憑證
- MySQL Host: 172.21.20.203 (從跳板機可解析/連線的 IP)
- MySQL Port: 3307

常駐服務化:Systemd / Inittab / Autossh
Systemd 服務 (Linux 客戶端推薦)
# /etc/systemd/system/mysql-tunnel@.service
[Unit]
Description=MySQL SSH Tunnel to %i
After=network.target
[Service]
User=tunnel_user
ExecStart=/usr/bin/ssh -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -L 3307:127.0.0.1:3306 %i
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
# 啟用
systemctl enable mysql-tunnel@db_user@192.168.1.100
systemctl start mysql-tunnel@db_user@192.168.1.100
Autoshrc (自動重連、輕量)
# 安裝 autossh
autossh -M 0 -fNg -o "ServerAliveInterval=60" -o "ServerAliveCountMax=3" -o "ExitOnForwardFailure=yes" -L 3307:127.0.0.1:3306 user@host
# -M 0 關閉監視埠,依靠 SSH 內建心跳
Inittab (傳統 SysVinit)
# /etc/inittab
tn:345:respawn:/usr/bin/ssh -Ng -L 3307:127.0.0.1:3306 user@remotehost.com
# init 會在進程死掉時自動重啟 (respawn)
Windows 客戶端常駐方案
- NSSM (Non-Sucking Service Manager):將
ssh.exe -fNg ... 封裝為 Windows 服務
- PuTTY/Plink:
plink.exe -batch -N -L 3307:127.0.0.1:3306 user@host -pw pass 配合任務排程器/啟動資料夾
- Windows 10+ OpenSSH Client:原生
ssh.exe,配合 NSSM 或啟動腳本
安全加固建議
- SSH 金鑰認證:禁用密碼登入,
PasswordAuthentication no,部署 Ed25519 金鑰
- 限制 SSH 用戶權限:
ForceCommand /bin/false 或 /usr/bin/nologin,僅允許轉發
- MySQL 僅監聽 127.0.0.1:
bind-address=127.0.0.1,拒絕直接網路存取
- 防火牆僅開放 SSH 埠:3306 完全內網/本地
- 審計日誌:SSH
LogLevel VERBOSE、MySQL 審計插件記錄所有查詢
常見問題排查
| 現象 | 原因 | 解決 |
| Channel open failed: connect failed | 目標主機:埠從 SSH Server 不可達 | 驗證 SSH Server 能否 telnet 172.21.20.203 3307 |
| Connection refused on local port | 本地轉發埠衝突/未生效 | 換埠、檢查 netstat -an | findstr 3307 |
| 隧道頻繁斷開 | 閒置超時/網路抖動 | 加 ServerAliveInterval=60、TCPKeepAlive yes |
| Navicat SSH 連不上 | 金鑰格式/權限/主機金鑰驗證 | 用 PuTTYgen 轉 .ppk、known_hosts 預載、允許密碼測試後再改鑰 |
總結
SSH 隧道是零成本、高安全、標準化的 MySQL 遠程存取方案。核心命令 ssh -fNg -L local:target:port user@ssh_host,配合 ServerAliveInterval、ExitOnForwardFailure、autossh/Systemd 常駐化。生產環境必須:金鑰認證、限制 SSH 用戶、MySQL 只聽 127.0.0.1、防火牆收斂。Navicat 等 GUI 內建 SSH 功能可免去命令列管理。
- 上一篇文章: MySQL 主機名/IP 解析機制深度解析:skip_name_resolve、Host 快取、DNS 效能優化
- 下一篇文章: MySQL 資料類型完整參考指南:數值、字串、日期時間、空間、JSON
Copyright ©
程式碼之家 All Rights Reserved