OpenSSHでトンネリング

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

Mac,Linuxの場合

 鯖1 (example.com) でSSHサーバが動いてて、グローバルIPアドレスを持たないが鯖1と同じネットワークにいる鯖2(192.168.1.10) につなぎたい、という場合 SSHトンネリングすると鯖2に直接接続つないでいるかのように扱うことが出来ます。

今、手元から 鯖2 の MySQL サーバにつなぎぐ場合の例です。MySQLのポートはデフォルトの 3306 とし、鯖1から接続が可能な状況とします。

以下のようにすると、自分のマシンの 19000番ポートが SSHトンネルを経由して鯖2の3306番 ポートに繋がります。

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

-L はローカルのポート指定、-l は example.com のSSHのユーザ名を指定します。詳細な書式は、下記です。

ssh -L{ローカルのポート番号}:{鯖2の、鯖1から見たhost}:{鯖2で接続したいポート番号} {鯖1のhost} -l {鯖1にSSHする際のユーザ名}

このとき、鯖1に接続可能な状態であればOKです。鍵認証でもパスワード認証でも問題ないです。鯖1から鯖2のポートに接続可能であれば、SSHトンネリングは完了です。

コマンドを実行すると、SSHで通常のログインしたのと同じ状態になりますが、閉じてしまうとトンネルも閉じてしまうので、そのままにしておきます。

もしくは、以下のように -f -N を付けてバックグラウンドで実行させておくことも出来ます。

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

SSHがつながった後は、localhost の 19000番ポートへMySQLでつなぎにいくと、鯖2の3306番ポートにMySQLしたのと同じようにつながります。

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

この例は MySQL ですが、注意点としてはホスト(-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使う例)

Windows の PuTTY でもSSHトンネリングが出来ます。

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

putty設定

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

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

DBやアプリケーションサーバは踏み台サーバ経由でアクセスすることが多いので、SSHトンネリングの設定を .ssh/config に書いておくと便利なことも多いかもしれません。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です