ssh ポート転送(port forwarding)


ポート転送とは

 ssh ポート転送とは他マシンにあるIPポートを、自マシンのポートとして 扱うための技のひとつといえよう。つまり、自マシンの特定ポートへの接続が sshサーバを介しての他マシンの指定ポートへの接続となる。

 具体的な例を挙げると、sshサーバのアドレスが192.168.111.1、プロキシ サーバのアドレス・ポート番号が192.168.111.200:8080 であるとする。ここで、 あるマシン192.168.222.10からsshサーバに接続し、ポート転送の設定で localhost:8080を192.168.111.200:8080へ転送するように設定していたとする。 192.168.222.10マシンのWebブラウザのプロキシ設定を「localhost:8080 (127.0.0.1:8080)」としたとき、それは、192.168.111.200を介してのブラウジ ングとなる。イメージは下図(100%MS-ペイント製なので見にくいですが)。

port転送図

 なぜこんなことをするのかというと、ファイヤーウォールの"穴"を通るためで ある場合が多いだろう。上記の192.168.222.10から192.168.111.200へ直接アクセス できるのであればこんなことする必要はないし、しないほうが速度も速いだろう。 つまり、「学内専用ページ」などにアクセスできるようにするためにssh用の"穴"を 利用するのである。sshでは暗号化通信が行えるため、"穴"があけられていること が多い。(なお、県大計算機センターシステムにも学外からのssh接続が可能 である。ただし学生が利用する場合、登録が必要である。詳しくはセンターのペー ジを参照のこと。)

 Windowsでssh接続する場合、ssh社の"Secure Shell"やttsshを使うのだろう か?(ワタシはこの2つしか使ったことがないので・・・)とにかく、どちらを 使ってもポート転送は実現できる。それぞれ、設定用のウインドウを開き、設定を 行う。

 Linuxの場合、"open-ssh"を使うのだろうか、詳しく知らないけど、「ssh コマンド」を使えば実現できる。


ポート転送する

 上述のプロキシの例を実現する場合、クライアントマシン(上記 192.168.222.10)で以下のようなコマンドを実行すればよい。

$ ssh -L 8080:192.168.111.200:8080 [ユーザ名@]192.168.111.1

 「-L」オプションで「ローカルホスト → リモート(転送先)ホスト」のポート 転送の設定ができる。「-L」に続けて、(ローカルのポート番号):(転送先のIPアドレス (またはマシン名)):(転送先ポート番号) を入れる。後は、通常ssh接続と同様に [ユーザ名@]接続先マシン を入れる。

 「-R」もポート転送のオプションである。こちらは「リモートホスト → ローカルホスト」のポート転送をするオプションである。つまり、指定したホストの 指定ポートへの接続が、あたかも自マシンへの接続のようになる(と思う)。

 ただし、このオプションではssh接続したマシンのみがポートを利用でき、 他のマシンからはこのポートを利用できない。


他のマシンからの利用

 -L オプションだけではローカルでしかポートが使えない。他のマシンからも 利用するためには「-g」オプションをつける。

$ ssh -g -L 8080:192.168.111.200:8080 [ユーザ名@]192.168.111.1

 これで他マシンからの利用が可能となる。


~/.ssh/config

 上記のようにすればポート転送ができるのはご理解いただけたであろう。 ただ、これではポート転送しようとするたびにコマンドラインに長々と オプションをつけることになる。毎回、いつもこんなことするのは嫌である。 そもそも、「ユーザ名@」や長ったらしいIPアドレスを毎回入力するのさえ 嫌気が差す。

 そんなとき使えるのが「~/.ssh/config」ファイルである。例えば、 ファイルの内容は次のようになる。

$ cd ~/.ssh
$ cat config
Host     univ
HostName 192.168.111.1
User     user01
GatewayPorts    yes
LocalForward    8080    192.168.111.200:8080
LocalForward    5900    192.168.111.123:5901
Host aaa
HostName 192.168.135.79
User taro

 "Host"から、次の"Host"までが1つの接続に関する設定情報となる。 まず、Hostはただのニックネームのようなもの(適当に名前を付ける)、HostNameは グローバルなマシン名・IPアドレス、Userは接続時のユーザ名、GatewayPortsは( 「-g」オプションに対応する)他マシンからのポート転送接続の可/不可 (yes/no、GatewayPorts省略時は no)、LocalForwardは(「-L」オプション に対応する)ポート転送先の設定で、(localのポート番号) と (転送先のIPアドレス(またはマシン名)):(転送先ポート番号)で示す。 これで、

$ ssh univ

$ ssh -g -L 8080:192.168.111.200:8080 -L 5900:192.168.111.123:5901 user01@192.168.111.1

は同じ意味を持つようになる。もっと楽をしたいなら 「alias univ="ssh univ"」とでも ~/.bashrc に書けばいいだろう( いっそのこと、「alias univ="ssh -g -L 8080:192....."」とかでも いいのだろうが・・・)。


ご注意を

 勘のいい方も、悪い方も気付いているかと思うが、要するに 「トンネリング」である。「-g」オプションなどで他ホストからの接続を許可し、 かつ、そのマシンがファイヤーウォールなどで外と遮断されていない場合、 先の場合のプロキシサーバは結局、全世界に公開されていることになる。プロキシ なら微妙な感じだが、telnet接続ポート(23か?)へのポート転送だと考えると・・・ 、ちょっと怖い。もちろん、sshサーバの管理者は誰が「変なの」を招いたかわかる だろうから、結局、sshユーザ(トンネル掘ったヤツ)が怒られる(くらいなら いいが)ことになる。「-g」オプションを使う場合、その点の注意が必要である。


もどる