ポートフォワードについてお勉強したのでメモ書きです。
- 上記画像のような構成で、ローカルの開発環境から、稼働環境のdb(MYSQL)に接続したい。
- dbはインターネットに公開されていない。
というような条件だったので、リモートのwebサーバ経由のポートフォワードで接続しました。
無理だった例
できればアプリケーションレベルで解決したかったので、php内で試行錯誤してみた。
$ssh_connection = ssh2_connect($ssh_host, $ssh_port); ssh2_auth_password( $ssh_connection, $ssh_user, $ssh_pass); $tunnel = ssh2_tunnel($ssh_connection, $db_host, 3306); $connection = mysql_connect($tunnel, $username, $password);
トンネルの確立まではできたけど、無理でした。
mysql_connect()はトンネルを受け付けないらしい。
また
$host = "ssh2.tunnel://user:pass@xx.xx.xx.1:22/xx.xx.xx.2:3306"; $connection = mysql_connect($host, $username, $password);
このようにssh2ラッパーを使う方法もダメでした。
mysqliはトンネルをサポートしているらしいが
$connection = new mysqli("{$db_host}:3306", $username, $password, $database, $tunnel);
今回のアプリケーションは古いコードで、dbとの接続にmysql_connect()を使用しており、この方法は使えない。
同様に、pdoもつかえない。
というわけで、アプリケーションレベルでの対応を諦める。
解決
sshコマンドをバックグラウンドで走らせておくことで解決させました。
ssh -f -g -N -C -L {ローカルポート}:{リモートdbホスト}:3306 {sshユーザ}@{リモートsshホスト} -p 22
- -g 他のマシンからも 利用する
- -f このポートフォワーディングをバックグラウンドで実行する。
- -N SSHトンネリングのみに使用する。
- -C データを圧縮して送る。
- -L ポートフォワードを利用する。
{ローカルポート} はローカルで空いてるポートだったらなんでもOK。
今回のサーバ構成例だとこんな感じ。
ssh -f -g -N -C -L 13306:xx.xx.xx.2:3306 user@xx.xx.xx.1 -p 22
これでローカルに対して接続したら、トンネルくぐって接続してくれます。
$connection = mysql_connect("127.0.0.1:13306", $db_username, $db_password);
もちろんPDOだろうがなんだろうが、接続できます。
ちなみに、phpのexec()で、sshコマンドを打ってみたが、なんかうまくいかなかった。
まぁ作業前にコマンド一本打つか、/etc/rc.d/rc.localにコマンド書いとくかすればいいかな。
参考にさせてもらったサイトはこちら
http://www.tamurasouko.com/?p=1092
https://www.kmc.gr.jp/advent-calendar/ssh/2013/12/09/tunnel2.html