20

ssh 経由で mysql サーバーへの ssh トンネルを確立したいと考えています。

理想的には、直接接続していたのと同じように、mysqli db ポインターを返します。

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 のトリックの詳細については、SSH とポート転送に関するBrian Hatch の優れたシリーズを参照してください。

于 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: トンネル接続に関しては、基本的に 2 つのオプションがあります。接続を常に開いたままにするか、開いて必要に応じて閉じるかです。私たちは後者を好みます。そのため、トンネルを確立するときにオプションを指定しません-N。これにより、プロセスが手動で強制終了されるまでトンネルが開いたままになります (自動化には適していません)。-Nが指定されていないため、トンネルは SSH セッションが使用されなくなるとすぐに閉じます。これは、トンネルを作成してからトンネル経由で MySQL 接続を確立して実行するまでの数秒を除いて、理想的な動作です。この期間中の時間を稼ぐために、無害なsleep 60トンネルが作成されたときにコマンドを実行します。これにより、基本的に、トンネルが閉じる前にトンネルを通過する他の何かを取得するために 60 秒かかります。その時間内に MySQL 接続が確立されていれば、準備は完了です。

于 2012-09-30T09:39:40.823 に答える
7

ルート認証情報と公開秘密鍵ペアの両方で SSH を実行してみました。コマンドラインから接続できますが、PHP コードからは接続できません。

また、(SSH2 関数を使用して) トンネルを作成し、PHP コード ( 、 など) からシェル コマンドを実行してみましsystemexec。何も機能しませんでした。

最後に、シェルコマンドを実行するためにSSH2機能を試してみましたが、最終的に機能しました:)

それがあなたを助けるなら、これが私のコードです:

$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 トンネルの初期化には長い時間がかかります (簡単に 1 ~ 2 秒かかる場合があります)。つまり、データベースに接続するすべてのページの読み込み中に 2 秒の遅延が発生します。

これを行う必要がある場合(これは強くお勧めしません)、最善の方法は、バックグラウンドで接続を維持するスクリプトを用意することです..

SSH キーペアをセットアップします。次に、autossh、または必要な SSH コマンドを実行する単純なスクリプトを使用して、プロセスが終了するまで待ってから、もう一度開始します。よりインテリジェントになり、10 ~ 20 秒ごとにコマンドを試行して実行し、失敗した場合は再接続することができます。

SSH キーペアを使用すると、スクリプトでリモート ユーザーのパスワードをハードコーディングする必要がなくなります。リモートユーザーができることを制限することをお勧めします(専用のトンネルユーザーを使用し、制限されたシェルを与えることにより、この質問を参照してください)

要するに、最初に SQLite を試してから、XML ファイルを使用してデータを保存することがどれほど実現可能かを確認し、ローカル MySQL サーバーの取得について Web ホストにバグを報告してから、SSH トンネリング オプションを調べることを強くお勧めします。

于 2008-11-22T06:07:03.263 に答える
1

最善の策は、別のホスティング プロバイダーを見つけることだと思います。Web ホストを完全に制御できる VPS ソリューション (Virtual Private Server) をお勧めします。そうすれば、デフォルトの構成が気に入らない場合は、自分でアップグレードできます。

于 2008-11-22T04:43:31.433 に答える
1

エリック、

あなたはこれで運が悪いと思います。PHP コードで ssh 拡張機能を使用するか、サーバーにアクセスできる場合は、コマンドラインで ssh トンネルの作成を試みることができます。

ただし、それを行うにはおそらく特別な権限が必要です。また、このホスティング アカウントへの ssh アクセス権がないようです。

――ジョアン

于 2008-11-21T18:53:45.930 に答える