在PHP中通过SSH连接到MySQL服务器

时间:2008-11-21 17:53:18

标签: php mysql ssh

我想通过ssh在我的mysql服务器上建立一个ssh隧道。

理想情况下,我会返回一个mysqli数据库指针,就像我直接连接一样。

我在共享主机上没有SSH2库,但我可以使用PECL在本地安装它们。

如果有一种方法可以使用很棒的本机命令。

我在考虑这样的事情,但如果没有这些库,它将无法工作。

$connection = ssh2_connect('SERVER IP', 22); 

ssh2_auth_password($connection, 'username', 'password');

$tunnel = ssh2_tunnel($connection, 'DESTINATION IP', 3307);

$db = new mysqli_connect('127.0.0.1', 'DB_USERNAME', 'DB_PASSWORD', 
                         'dbname', 3307, $tunnel)
    or die ('Fail: ' . mysql_error());  

有人有什么想法吗?我在liquidweb运行一个共享的CentOS linux主机。

关于使隧道持久的任何想法?是否可以使用其他脚本建立它并在PHP

中利用它

感谢。

6 个答案:

答案 0 :(得分:14)

我会使用autossh工具为你的mysql数据库创建一个持久的ssh隧道。然后,您在PHP代码中所要做的就是将它指向localhost。

您可以通过执行以下操作来测试(无需自动重启):

ssh -L 3306:localhost:3306 user@domain.com

设置一个ssh密钥,这样你就不需要使用密码,并调整mysql系统上的.ssh / authorized_keys文件,只允许它用于端口转发。

有关ssh技巧的更多信息,请参阅Brian Hatch's关于SSH和端口转发的优秀系列。

答案 1 :(得分:6)

我通过root凭据和公共私钥对进行SSH尝试。它允许我通过命令行但不通过PHP代码进行连接。

我还试过创建隧道(使用SSH2函数),并从PHP代码(systemexec等)运行shell命令;没有用。

最后我尝试了SSH2函数来执行shell命令,最后它起作用了:)

这是我的代码,如果它可以帮助你:

$connection = ssh2_connect($remotehost, '22');
if (ssh2_auth_password($connection, $user,$pass)) {
    echo "Authentication Successful!\n";
} else {
    die('Authentication Failed...');
}


$stream=ssh2_exec($connection,'echo "select * from zingaya.users where id=\"1606\";"  | mysql');
stream_set_blocking($stream, true);
while($line = fgets($stream)) {
    flush();
    echo $line."\n";
}

如果想特别使用PHP函数,请尝试此操作。

答案 2 :(得分:6)

在SQL操作过程中,隧道必须保持打开状态。以下来自RJMetrics的示例解释了:

这是通用的SSH命令语法:

ssh -f -L bind-ip-address:bind-port:remote-ip-address:remote-port \
username@remote-server [command] >> /path/to/logfile

以下是仅使用2行PHP代码安全地建立远程数据库连接的方法:

shell_exec("ssh -f -L 127.0.0.1:3307:127.0.0.1:3306 user@remote.rjmetrics.com sleep 60 >> logfile");  
$db = mysqli_connect("127.0.0.1", "sqluser", "sqlpassword", "rjmadmin", 3307);

我们使用shell_exec()函数创建具有60秒打开窗口的隧道,然后使用mysqli_connect()函数使用转发端口打开数据库连接。请注意,我们必须使用" mysqli"这里的库是因为mysql_connect()不允许我们指定端口,并且不推荐使用mysql_*函数。

sleep 60:当谈到隧道连接时,我们基本上有两个选择:保持连接始终打开或打开它并根据需要关闭它。我们更喜欢后者,因此我们在建立隧道时不指定-N选项,这会使其保持打开状态,直到手动终止该过程(对自动化不利)。由于未指定-N,因此只要SSH会话不用于任何事情,我们的隧道就会自动关闭。这是理想的行为,除了我们创建隧道和通过隧道运行MySQL连接之间的几秒钟。为了在这段时间内给我们买一些时间,我们在创建隧道时发出无害sleep 60命令,这基本上会让我们花60秒才能在隧道关闭之前通过隧道获得其他东西。只要在该时间范围内建立了MySQL连接,我们就可以了。

答案 3 :(得分:3)

可能,但为什么呢?它比它需要的更复杂,而且容易出错。

你能不在本地运行数据库?如果没有,您是否可以使用SQLite,XML文件或其他不需要单独的服务器守护程序的东西?

确实不希望在PHP脚本中初始化隧道。初始化SSH隧道需要很长时间(很容易就是一两秒),这意味着连接到数据库的每个页面在加载时都会有2秒的延迟..

如果您来执行此操作(我强烈建议您这样做),最好的方法是拥有一个在后台维护连接的脚本。

设置SSH keypair。然后使用autossh或执行所需SSH命令的简单脚本,等待进程死亡并再次启动它。它可能更智能,每10-20秒尝试运行一次命令,如果失败则重新连接。

使用SSH密钥对,您不必在脚本中对远程用户密码进行硬编码。我建议限制远程用户可以执行的操作(通过使用专用隧道用户,并为其提供受限制的shell,请参阅this问题)

简而言之,我强烈建议先尝试SQLite,然后看看使用XML文件存储数据的可行性,然后尝试窃听你的网络主机关于获取本地MySQL服务器,然后查看SSH隧道选项。

答案 4 :(得分:1)

埃里克,

我认为你在这一点上运气不好。您可以在PHP代码中使用ssh扩展,或者如果您有权访问服务器,则可以尝试在命令行上创建ssh隧道。

但是,您可能需要特殊权限才能执行此操作。看起来您还没有ssh访问此主机帐户。

- 若昂

答案 5 :(得分:1)

我认为您最好的办法是寻找不同的托管服务提供商;我建议使用VPS解决方案(虚拟专用服务器),它可以让您完全控制您的Web主机。但是,如果您不喜欢默认配置,可以自行升级。