Wednesday, January 9, 2013

sshトンネル作成時の -L 指定値

昨日も触れた ssh トンネルの張り方は、ぐぐると非常にたくさん解説が出てくるのだが、以下の図のように、作成したsshトンネルの入り口を仮想的にターゲットのサーバのようにみたてて使いたい場合、ぐぐってもあまり出てこない留意事項があるのでメモ。

「ローカルPC」から「乗り込み先」に tcp 443 (SSL)で接続したいのだが、「ローカルPC」上で tcp 443 が他アプリに使われているとか、複数人で共有したいため、sshトンネルの入り口は「踏み台(自拠点)」に開設したいということである。

ぐぐって出てくる一般的な解説では、上記のトンネル#1を開設する際に ssh に指定するパラメータは、

  -L 443:10.0.0.123:65443

ということになっている。(65443 は例)

しかしこれだと、図の「踏み台(自拠点)」マシン上で、 127.0.0.1:443 (tcp) で LISTEN 状態のTCPソケットが作成されてしまい、図の「ローカルPC」から接続できない。

さて、man ssh して -L の説明を読むと、こんなことが書いてある。

     -L [bind_address:]port:host:hostport

             Specifies that the given port on the local (client) host is to be
             forwarded to the given host and port on the remote side.  This
             works by allocating a socket to listen to port on the local side,
             optionally bound to the specified bind_address.  Whenever a con-
             nection is made to this port, the connection is forwarded over
             the secure channel, and a connection is made to host port
             hostport from the remote machine.  Port forwardings can also be
             specified in the configuration file.  IPv6 addresses can be spec-
             ified by enclosing the address in square brackets.  Only the
             superuser can forward privileged ports.  By default, the local
             port is bound in accordance with the GatewayPorts setting.  How-
             ever, an explicit bind_address may be used to bind the connection
             to a specific address.  The bind_address of ``localhost'' indi-
             cates that the listening port be bound for local use only, while
             an empty address or '*' indicates that the port should be avail-
             able from all interfaces.

赤字で強調した(省略可能な) [bind_address:] のところがポイントで、図のように使いたい場合は

  -L 0.0.0.0:443:10.0.0.123:65443

と、bind する IP address を明示的に指定してやる必要がある。
0.0.0.0 は言うまでもなく INADDR_ANY で、任意のIP addressにマッチする。
図の「踏み台(自拠点)」が複数のNICを持っていて、特定の IP に制限したい場合は、

  -L 192.168.100.2:443:10.0.0.123:65443

等と、適切な unicast IP address を書くこと。

さて、話はまだ続く。

     -L [bind_address:]port:host:hostport

の赤字強調した2番目の host には、一般的には接続先の IP address を書くと解説されているし、実際、man page の説明もそう読める。

しかし、ここはどんな IP address を書いても無視され、コマンドラインとしては

  $ ssh   -L [bind_address:]port:host:hostport    user@remote_host

と指定した時の remote_host (図のトンネル#1では「踏み台(他拠点)」のインターネット側IP addressに対応)が使われる。(ので、実は、どんな IP address を書いてもかまわない)

# Apr. 27, 2013 追記 begin

上記の記述に誤りがありました。
この記事では、


  $ ssh   -L [bind_address:]port:destination_host:hostport    user@remote_host

と記述した場合の destination_host と remote_host が同じサーバである場合を想定していました。
なので、この場合に限っては上に書いたとおりになるのですが、remote_host に中継させて、
さらに remote_host から IP reachable な別の destination_host に対して forwarding させることも
できます(というか、本来の SSH port forwarding の趣旨はこちらになります)
ですので、「さて、話はまだ続く」以下は間違っています。
destination_host の指定値には、とても重要な意味があります。

訂正してお詫びいたします...
# Apr. 27, 2013 追記 end





いや、紛らわしいですね...

No comments:

Post a Comment