筆者はVMware2.0で、 ホストOS(本来のマシンで動いているOS)をWindows2000、 ゲストOS(vmwareが作りだした仮想マシンで動くOS)をLinuxにして使っている。 この仮想ネットワークをhost-onlyで使っているのだが、 ゲストOSから見えるマシンがホストOSしかないので、 外のマシンとのデータ交換が非常に不便だった。
これに対し、HTTP-tunnelingと呼ばれるテクニックで、 ゲストOSから外部ネットワークに接続することができたので、 記事にまとめることにした。
社内ネットワークなどでインターネットへの出口がproxyしかない、 などという状況でも同様のテクニックでsshで外に出られる。 というか、筆者のような状況よりは、 むしろそういう状況で利用するパターンの方が多いだろう。
VMwareを知らないと意味不明かもしれないが、 VMwareが無い場合でも何かの助けになればと思っているので、 やや丁寧に書いているつもり。
要は、VMware2.0 on Windows + host-only network の環境で、 HTTP-tunnelingとwindowsのローカルプロクシを使って ゲストOSからsshで外に出よう、という記事です。
筆者の場合、VMwareのインストール時にbridgedの設定をしくじって さっぱりうまくいかなかったので、host-onlyで我慢することにしました。 同様の環境であってもVMware3.0ではNATが使えるだろうし、 VMware2.0でもインターネット共有で使っている人の方が多いかと思いますが、 こんな方法もあるよ、ということで。
Vmwareユーザーじゃない人のためにhost-only networkについて説明しておきます。 VMwareをhost-onlyでインストールすると、 ホストOS(ネイティブOS。今回の場合はWindows)と ゲストOS(vmware上のOS。今回の場合はLinux)にそれぞれ 仮想的なNICが一つ作られ、 この2マシンのみを繋ぐプライベートネットワークが組まれます。 これがhost-onlyと呼ばれる仮想ネットワークです。 名前の通り、この2マシン間の通信にしか使うことができません。
今回の場合、Windowsには172.22.0.1を、 Linuxには172.22.0.101を、それぞれ割り振りました。 Windows側で特に何も設定をしていませんので、 Linuxからは直接インターネットは見ることができません。
筆者の環境は以下のとおりです。
Proxomitronは別ページで説明してあるので見てもらうとして、 さらにVMwareからアクセスできるようにする必要があります。 今回の例であれば、設定ウインドウの「Config」-「Access」で 172.22.0.2から172.22.0.254まで許可、 もしくは172.22.0.101からのみ許可などとしておきます。
要するに、外のネットワークが見えて、かつSSLも通せるようなproxyを使うと、 sshが通せる、って話です。 SSLが通るproxyでは、実は全てのプロトコルが通せるのです。 もちろん制限があったりもするが、どうってことはありません。 (これに関しては後述)
どういうことかというと、 proxyに対して普段はGETとかHEADとかPOSTとかのメソッドを使うわけだが、 CONNECTというメソッドがあって、 SSLやsshなどの面倒なプロトコルを通す場合にはこれを使う。 例えば、172.22.0.1:8080にproxyが立っている場合、
$ telnet 172.22.0.1 8080 Trying 172.22.0.1... Connected to 172.22.0.1. Escape character is '^]'. CONNECT 172.22.0.101:22 HTTP/1.0 HTTP/1.0 200 Connection established SSH-1.5-OpenSSH-1.2.3
となって、別のサーバのsshdにつなぐことができる。 つまり、proxyにアクセスできるマシンならば proxyがアクセスできるネットワークどこにでもアクセスできちゃう。 (この仕組みをHTTP-tunnelingとか言うらしい) もう一ひねりすればsshで接続できそうでしょ?
で、その一ひねりの準備がOpenSSHには用意されている。 ProxyCommandというのがそれで、 ssh_configに書くことで、接続のためのfilter(外部コマンド)を書ける。 つまり、proxyに対してCONNECTをして、 残りの入出力を素通しするようなコマンドがあれば、 proxy越しのsshが使えちゃうというわけ。
で、そのfilterを作ればいいわけだが、 自作せずとも用意してくれている方がいるので、 ありがたく使うことにする。 SSH Proxy Command -- connect.c がそれ。英語のみですが詳細な説明があります。
何やらsocksに対応してたりして、こだわりの品って感じ。 まあ、筆者はhttp-proxy使うだけなのでオーバースペックなのだが。
$ gcc -o ~/bin/proxy-connect connect.c
などとして、~/.ssh/configの先頭に
ProxyCommand /home/hanawa/bin/proxy-connect -H 172.22.0.1:8080 %h %p
とやってできあがり。
しかし、Proxomitronはこんな使い方でも全く問題ない。 SSLを通すんだから正常に動作して当然なのかもしれないが、 作者も想定外の使い方なんじゃないだろうか。
VMware内からホスト名を解決するのは不可能でも、 この枠組だとProxyで名前解決してくれるので、 いちいちIPとホスト名の対応を書く必要もなくて幸せ。
以上で筆者の使い方ではバッチリなのですが、 世間一般ではCONNECTで443番(SSL)にしかつなげない設定になっているproxyの方が普通です。 CONNECTメソッドをSSL以外に使うな、ってことなんでしょうが、 世の中443番以外にSSLが立っていることはありえないんですかねえ? そんなことだからいつまでもベリサイン丸儲けなんだよなあ、などと愚痴りつつ、 対策を考えてみます。
まず思いつく対策は、接続したいサーバの443番にsshdを立ててしまうことです。 または、対象のproxyがsquidのデフォルト設定のままで運用している場合には、 563番も利用できるかもしれません。
もしくは、問題のproxyから443番を叩きに来たときのみ、 22番にREDIRECTするようipchainsの設定をする、 などというのもアリかと思います。
残念ながら、どちらも無理という場合には打つ手なしかな…。 proxy管理者を丸め込んで、22番も開けさせましょう。 squidの場合の設定はそれほど難しくありませんが、 公開proxyでこれをやると踏み台にされる可能性もあります。ご注意を。 社内pxoryの場合には、 各個人が変な経路で穴を空けるのに比べれば経路を一元化できるので、 悪くない設定だろうと思います。 まあ、そんな意見が通るとは限らないですけど。
こんな記事より素晴らしい文章がいっぱいあります。 この記事のような妙な環境でやった例は見たことないですが、 目先が変わっているだけで技術的には他の環境と同じことをしていますので、 下記リンクが参考になると思います。
あ、どっかで聞いた名前だと思ったらstoneの作者だ>仙石さん
hanawa<y@hnw.jp>$Date: 2004-10-06 04:58:03 $