20

我想通过 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

谢谢。

4

6 回答 6

16

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

您可以通过以下方式对此进行测试(无需自动重启):

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

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

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

于 2008-11-22T05:44:32.560 回答
10

在 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 连接,我们就都准备好了。

于 2012-09-30T09:39:40.823 回答
7

我通过根凭据和公钥对执行 SSH 来尝试它。它允许我通过命令行而不是通过 PHP 代码进行连接。

我还尝试通过创建一个隧道(通过使用 SSH2 函数),并从 PHP 代码(,等)运行 shellsystem命令exec;没有任何效果。

最后我尝试了 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 函数,试试这个。

于 2009-01-23T11:22:16.947 回答
3

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

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

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

如果您必须这样做(我强烈建议不要这样做),最好的方法是拥有一个在后台维护连接的脚本..

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

使用 SSH 密钥对,您不必在脚本中硬编码远程用户密码。我建议限制远程用户可以做什么(通过使用专用隧道用户,并给它一个受限的外壳,请参阅这个问题)

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

于 2008-11-22T06:07:03.263 回答
1

埃里克,

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

不过,您可能需要特殊权限才能执行此操作。您似乎也没有对此主机帐户的 ssh 访问权限。

——若昂

于 2008-11-21T18:53:45.930 回答
1

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

于 2008-11-22T04:43:31.433 回答