OpenSSHでトンネリング

 外部から見えないサーバへつなぐ必要があって、SSHのトンネリングというのをやってみた。

Mac,Linuxの場合

 example.com(鯖1) でSSHサーバが動いてて、外部ネットワークから直でつながってなくて鯖1からみたら同一ネットワークにある鯖2(192.168.1.10)という構成があるとする。今、外部から鯖2 へMySQLでつなぎたいと思う。MySQLのポートはデフォの3306とする。そのとき、以下のようにすると、自分のマシンの19000番ポートが鯖2の3306番ポートとつながる。

$ ssh -L19000:192.168.1.10:3306 example.com -l username

-L はローカルのポート指定、-l は example.com のSSHのユーザ名を指定。

 このコマンドを実行すると、ssh username@example.com としたときと同じことが起きるので、パスワードを入力する。するとSSHでつながる。これは閉じずにこのままにしておく。閉じちゃうと接続切れちゃう。以下のように -f -N を付けるとバックグラウンドで実行してるような感じになる。

$ ssh -f -N -L19000:192.168.1.10:3306 example.com -l username

 で、これやったあとは localhost の 19000番ポートへMySQLでつなぎにいくとつながる。

$ mysql -u testuser -p --port=19000 -h 127.0.0.1

 注意点は、ホスト(-hオプション)を 127.0.0.1に指定するということです。デフォでlocalhostなのに?と思うんですが、MySQLは localhost と 127.0.0.1 の扱いが違います。localhost は ローカルのソケットを通して接続を行なうのですが、127.0.0.1 はTCPソケットで127.0.0.1で接続を行ないます。今回は、ローカルのソケットでつなぐのではなく、TCPソケットでつなぐことになるので明示的に -h 127.0.0.1 を指定する必要がある。

Windowsの場合(putty使う)

 上の構成と同じ場合のputtyの設定。つなぐ画面の 接続 -> SSH -> トンネル という項目を設定します。以下のように、源ポート(自分のマシンでLISTENする任意のポート)と送り先ポート(SSHログイン先から見たホストとポート)を設定します。

putty設定

 この状態で普通にSSHでつなぐときと同じようにホスト名いれて、ユーザ、パスワードを入力すればSSHでログインされます。この状態でトンネリングが出来てるので、puttyは閉じないでそのままにしておきます。

 あとはMySQLクライアントで127.0.0.1の19000番ポートへつなぎに行けばつながります。

OpenSSHでトンネリング