web-dev-qa-db-ja.com

PHPでSSHを介してMySQLサーバーに接続します

リモートLinuxマシンにデータベースがあり、SSHとPHP関数を使用して接続したい(現在はssh2ライブラリーを使用している)。mysql_connectを使用してみたが、これでできるこの機能を使用しようとしたときのアクセス権(許可は与えていますが):

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

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

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

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

「mysqli_connect()はパラメータ6が文字列であり、リソースが指定されていることを期待しています」というエラーが発生しました。どうすればこれを解決できますか?

21
spooja

これを試して:

ステップ1。

MySQLデータベースサーバーへのSSHトンネルを設定します(セキュリティのために、Jumpbox経由が望ましい)。

ssh -fNg -L 3307:10.3.1.55:3306 username@ssh_jumpbox.com

ここで重要なのは-Lで、ローカルポートフォワーディングを実行していることを示しています。

ローカルポート転送構文
構文は少しトリッキーですが、次のように見ることができます:

<local_workstation_port>:<database_server_addr_remote_end_of_tunnel>:<database_server_port_remote_end>
username@ssh_proxy_Host.com 

他のスイッチに興味がある場合は、次のとおりです。

-f(バックグラウンドに移動)
-N(リモートコマンドを実行しない)
-g(リモートホストが転送されたローカルポートに接続することを許可します)

秘密鍵認証、上記に(-i)スイッチを追加:

-i/path/to/private-key

ステップ2。

ローカルMySQLクライアントに、マシンのローカルポート3307(-h 127.0.0.1)を介してSSHトンネル経由で接続するように指示します。これにより、ステップ1で確立したSSHトンネル経由で送信されたすべてのトラフィックが転送されます。

mysql -h 127.0.0.1 -P 3307 -u dbuser -pパスフレーズ


クライアントとサーバー間のデータ交換は、暗号化されたSSH接続を介して送信され、安全です。


NB:データベースサーバーに直接トンネリングすることはお勧めしません。インターネットから直接アクセスできるデータベースサーバーを用意することは、大きなセキュリティ上の責任です。トンネルターゲットアドレスをジャンプボックス/要塞ホストのインターネットアドレス(手順1の例を参照)に、データベースターゲットをリモートネットワーク上のデータベースサーバーの内部IPアドレスにします。 SSHが残りを行います。


ステップ3。

PHPアプリケーションを次のように接続します:

<?php
      $smysql = mysql_connect( "127.0.0.1:3307", "dbuser", "passphrase" );
      mysql_select_db( "db", $smysql ); 
?>

http://chxo.com/be2/20040511_5667.html にあるChris Snyderのすばらしい記事の功績


GUIツール

要件に応じて、別のアプローチとして、SSHトンネリングがサポートされているGUI MySQLクライアント( http://www.sequelpro.com/ など)を使用するか、PuTTYを使用してポート転送を設定します。

UPDATE 1今日、私は secure pipes と呼ばれる実行可能な代替macOS GUI sshトンネリングツールをレビューしました。

39
Tony Barganski

私は同じことを探していましたが、外部コマンドを必要とせず、外部プロセスを管理したくありません。したがって、ある時点で、純粋なPHP任意のPHPストリームで動作できるMySQLクライアントを作成することはどれほど難しいのでしょうか?約半分かかりました。 MySQLプロトコルのドキュメントに基づく1日。

https://Gist.github.com/UCIS/4e509915ed221660e58f5169267da004

これはSSH2ライブラリまたは他のストリームで使用できます。

    $ssh = ssh2_connect('ssh.Host.com');
    ssh2_auth_password($ssh, 'username', 'password');
    $stream = ssh2_tunnel($ssh, 'localhost', 3306);
    $link = new MysqlStreamDriver($stream, 'SQLusername', 'SQLpassword', 'database');
    $link->query('SELECT * FROM ...')->fetch_assoc();

これは完全なmysqli APIを実装していませんが、すべてのプレーンテキストクエリで動作するはずです。これを使用する場合は注意してください。コードのテストはまだ十分ではなく、文字列エスケープコードは確認されていません。

2
Ivo Smits

残念ながら、phpが提供するssh2トンネルは、トンネルするローカルポートを指定できないため、リモートmysql接続を処理できないようです(ポート22またはリモートサーバーが実行されているsshポートでのみ機能します)。これに対する私の解決策は、exec()演算子を使用してトンネルを開き、そこから通常どおりに接続することです。

exec('ssh -f -L 3307:127.0.0.1:3306 [email protected] sleep 10 > /dev/null');
$mysqli = new mysqli('127.0.0.1', 'user', 'password', 'database', '3307');
2
billynoah

the docs によると、最後のパラメータは '/var/run/mysql/mysql.sock'のようなソケット名またはパイプ名であると想定されています。 UNIXソケットを使用して接続していないので、それは当てはまりません...そのままにしておいてください。

1
David Z

ルート認証情報と公開秘密鍵のペアの両方でsshを実行して試しましたが、phpコードではなくコマンドラインで接続できます。私もトンネルを作成して(ssh2関数を使用して)、phpコード(システム、実行など)からシェルコマンドを実行してみましたが、何も機能しませんでした。最後に私はシェルコマンドを実行するために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関数を具体的に使用する場合は、これを試してみました。

0
spooja

Mysqlサーバーのユーザーが「localhost」からのみ許可するように設定されており、127.0.0.1ではなく、localhostのIPアドレスを許可するように設定されているためです。

私は次の手順を実行してこれを機能させました:

ステップ1:ターゲットユーザーに127.0.0.1ホストを許可する

通常はサーバーにSSH接続し、mysql rootユーザーでログインして、次のコマンドを発行します。

GRANT ALL ON yourdbname.* TO [email protected] IDENTIFIED BY 'yourdbpassword';

もちろん、キーは上記の127.0.0.1を指定することです。

ステップ2:MySQLへのローカルSSHトンネルを開始する

次のようにして、リモートMySQLサーバーへのローカルSSHトンネルを開始できます。

ssh -vNg -L 33306:127.0.0.1:3306 [email protected]

-vは、sshを詳細モードで動作させます。これは、何が起こっているかを確認するのに役立ちます。たとえば、接続を試みると、ターミナルコンソールに次のようなデバッグ出力が表示されます。

debug1: client_input_global_request: rtype [email protected] want_reply 0
debug1: Connection to port 33306 forwarding to 127.0.0.1 port 3306 requested.

接続を閉じると、次のように出力されます。

debug2: channel 2: is dead
debug2: channel 2: garbage collecting
debug1: channel 2: free: direct-tcpip: listening port 33306 for 127.0.0.1 port 3306, connect from 127.0.0.1 port 52112 to 127.0.0.1 port 33306, nchannels 3

-Nを指定すると、sshはコマンドを発行せず、接続を確立した後に待機します。

-gを使用すると、リモートホストが転送されたローカルポートに接続できます。これが必要かどうかは完全にはわかりませんが、同じSSHトンネルを介して複数の接続を多重化する場合に役立ちます。

-Lこれは、リモートホストのローカルIPアドレス33306に接続するローカルポート127.0.0.1およびリモートホストのmysqlポート(通常は3306)を指定するメインパラメーターです。

この後に必要なメカニズムやその他のパラメーターを使用して、SSH経由でリモートホストに接続できます。私の場合、~/.ssh/configで構成されたキーファイルを使用しているので、user@Hostを指定するだけで取得できます。

このようなコマンドを発行すると、SSHがフォアグラウンドで実行されるため、Ctrl + Cで簡単に閉じることができます。このトンネルをバックグラウンドプロセスで実行する場合は、-fを追加してこれを実行できます。

ステップ3:PHP /他のmysql互換メソッドから接続する

ローカルホストで上から実行されているSSHトンネルは、mysqlが127.0.0.1で実行されているかのように動作します。ポート33306(トリプル3に注意)を使用して、ローカルのSQLサーバーを通常のポートで実行できるようにします。これで、通常どおりに接続できます。端末のmysqlコマンドは次のようになります。

mysql -h 127.0.0.1 -P 33306 -u yourmysqluser -p

ここで、-P(大文字のP)は、SSHトンネルのローカルエンドが接続を受け入れるポートを指定します。 mysql cliはLinuxソケットを使用して接続しようとするため、localhostではなく127.0.0.1 IPアドレスを使用することが重要です。

PHP接続文字列の場合、データソース名文字列(Yii2構成の場合)は次のようになります。

'dsn' => 'mysql:Host=127.0.0.1;dbname=yourdbname;port=33306',

パスワード、およびユーザー名は通常どおり指定されます。

0
Dhiraj Gupta

接続先のユーザー名とパスワードに、適切なホスト名権限があることを確認してください。ワイルドカードに '%'を使用できると思います。また、ローカルネットワーク上にないリモートマシン(sshを実行しようとしている場合に想定)に接続している場合は、外部トラフィック用のサーバーがあるルーターのポートを転送する必要があります。接続できます。

http://www.lanexa.net/2011/08/create-a-mysql-database-username-password-and-permissions-from-the-command-line/

0
robert thornton