如何通过PHP+SSH连接远程MySQL?连接被拒问题排查
问题排查与修复方案
核心错误点
PDO连接地址错误
你建立的SSH隧道是将本地33065端口转发到远程服务器的$dbhost:33060,所以PDO连接时的host必须是127.0.0.1(本地回环地址),而非远程的$dbhost。原代码用$dbhost连接本地33065端口,相当于让本地客户端去远程主机找33065端口,这个端口不存在,直接导致连接被拒绝。SSH隧道未持久化
原命令里的sleep 5会让ssh进程在5秒后退出,隧道随之关闭。当PDO尝试连接时,隧道大概率已经失效。需要让ssh在后台持续运行,而非仅前台存活几秒。
修复后的代码
// 建立后台持久化隧道:-fN让ssh后台运行,关闭StrictHostKeyChecking避免首次连接的交互阻碍 shell_exec("sshpass -p SSHPASS ssh -fN -o StrictHostKeyChecking=no -L 127.0.0.1:33065:$dbhost:33060 SSHUSER@SSHHOST"); // 连接本地转发的端口,host指定为127.0.0.1 $dbh = new PDO("mysql:host=127.0.0.1;dbname=$dbname;port=33065", $dbuser, $dbpass);
额外排查项
- PHP进程权限:确认运行PHP的用户(如Apache的
www-data、Nginx的nginx)有权限执行sshpass和ssh命令,且能访问对应执行文件的路径。 - 端口占用验证:Linux下执行
netstat -tulpn | grep 33065,Windows下执行netstat -ano | findstr :33065,确认隧道建立后本地33065端口是否被ssh进程占用。 - 远程MySQL配置:检查远程MySQL的
my.cnf,确认bind-address允许SSH服务器所在IP访问(如果$dbhost是远程服务器的127.0.0.1,此条可忽略;如果是公网IP,需确保MySQL对外开放该IP的访问权限)。 - sshpass安装状态:在服务器执行
sshpass -V,确认已安装该工具。
内容的提问来源于stack exchange,提问作者Lars
相关产品推荐
相关产品推荐

