透過型プロキシ (Transparent Proxy) というのは、 ブラウザから 「見えない」 プロキシのこと。 ブラウザ自身は WWW サーバにアクセスしているつもりなのに、 ブラウザが送信したリクエストをプロキシが横取りし、 プロキシから出し直す。 サーバからのレスポンスは当然プロキシに返り、 プロキシがそれをブラウザに送信するのだけど、 パケットがブラウザに届くまでの間に送信元アドレスが書き換えられて、 サーバから直接レスポンスが届いたようにブラウザからは見える。
フツーの 「見える」 プロキシは、 ブラウザ等でプロキシ設定が必要であるのに対し、 透過型プロキシだと設定が不要。 だから一部の ISP (インターネット接続プロバイダ) などで、 フツーのプロキシの代りに使われていたりする (ユーザにプロキシ設定の方法を説明する必要がなくてサポートコストが削減できる)。 あるいは企業等で、 従業員が仕事と関係ない Web ページを閲覧していないか監視するために、 社内から社外へ接続するゲートウェイ等に透過型プロキシを設置して、 社外への http アクセスを記録していたりする (監視だけならパケットをダンプするだけでも用が足りるが、 アクセス先のサイト毎に細かな制御を行なおうとすると、 プロキシを使った方が楽)。
このように、 透過型プロキシはその存在を隠すために使われることが多いが、 ブラウザにプロキシ設定の機能が無い場合は、 透過型プロキシを使わざるを得ない。 例えば、 Android 端末で使われるブラウザの多くが、 なぜかプロキシ設定の機能を持っていない。 プロキシ経由でアクセスされると、 モバイル端末からのアクセスなのか、 フツーの PC からのアクセスなのか、 区別がつかなくなってしまうので、 あえてプロキシ設定できないようにしているのかも知れないが、 プロキシを使わないとアクセスできない場合は困ってしまう。
私の場合、 勤務先の LAN 内のサーバに社外からアクセスするとき、 社内アクセス専用のプロキシ (ここでは仮にホスト名を proxy.klab.org とする) を利用している。 例えば senri.gcd.org (自宅のサーバ、つまり社外) からこのプロキシをアクセスすると、 こんな感じ:
senri:~ $ openssl s_client -connect proxy.klab.org:443 -cert cert.pem -key key.pem -CApath /usr/ssl/certs -quiet↓ Enter pass phrase for key.pem:xxxxxxxx↓ depth=1 /C=US/O=Equifax/OU=Equifax Secure Certificate Authority verify return:1 depth=0 /serialNumber=-cn4oMJtlqoqfQZaTat68U68dNVbM8iQ/C=JP/O=*.klab.org/OU=GT41256819/OU=See www.rapidssl.com/resources/cps (c)09/OU=Domain Control Validated - RapidSSL(R)/CN=*.klab.org verify return:1 CONNECT irc.klab.org:6667 HTTP/1.1↓ ↓ HTTP/1.0 200 OK :irc.klab.org NOTICE AUTH :*** Looking up your hostname... :irc.klab.org NOTICE AUTH :*** Found your hostname
行末に 「↓」 がある行が入力行。 「↓」 は Enter キー押下。 秘密鍵 key.pem でクライアント認証を受けて proxy.klab.org に接続し、 CONNECT リクエストを送信することにより、 社内の任意のサーバ:ポートに接続できる。 上記の例では社内 IRC サーバである irc.klab.org:6667 に接続しているが、 もちろん社内の任意の WWW サーバにも接続できる。
説明を簡単にするため proxy.klab.org と書いたが、 実際には VPN Warp を使っている (だから proxy.klab.org というサーバは存在しない)。 VPN Warp も stone で接続することができるので、 以下の説明は VPN Warp の場合もほとんど同様に適用することができる。
プロキシというと、 ファイアウォールの内側から外部のインターネットをアクセスするために用いるものと思っている人が多いせいか、 外からファイアウォールの内側をアクセスするためのプロキシは、 特にリバースプロキシ (reverse proxy) と呼ばれることもある。
proxy.klab.org を透過型プロキシとして利用できれば、 社内の任意のサーバに透過的にアクセスできるようになる。 例えばこんな感じ:
senri:~ $ adb shell↓ $ getprop ro.build.description↓ soju-user 2.3.4 GRJ22 121341 release-keys $ su↓ # busybox traceroute irc.klab.org↓ traceroute to irc.klab.org (10.10.0.18), 30 hops max, 38 byte packets 1 110.158.20.29 (110.158.20.29) 701.203 ms 90.517 ms 85.570 ms 2 * * * 3 * * * 4 110.158.18.138 (110.158.18.138) 79.540 ms !A * * 5 * * * 6 * ^C senri:~ $ adb shell↓ $ telnet irc.klab.org 6667↓ :irc.klab.org NOTICE AUTH :*** Looking up your hostname... :irc.klab.org NOTICE AUTH :*** Found your hostname
「soju-user 2.3.4 GRJ22」 つまり Android 2.3.4 な Nexus S で、 パケットが届かないはずの irc.klab.org (10.10.0.18) に対して、 telnet でアクセスできている。 telnet でアクセスできるということは、 もちろん任意の IRC アプリで irc.klab.org にアクセスできるということ。
VPN (Virtual Private Network) でも同じことができる! という声が聞こえてきそうだが、 VPN だと TCP でデータを送受信していないときも、 VPN セッションを張っているだけでいろんなパケット (例えば ARP) が行き交って、 そのたびに電波が飛んで電池を消耗するので、 あまりモバイル向きではないと思う。
あるいは、 ConnectBot などを使って ssh で port forward を行なう方法もあるが、 これまた ssh セッションを張りっぱなしだと電池消耗が心配だし、 かといって IRC を使う前に毎回 ssh 接続を行なうのはメンドクサイ。 また、 通信先/宛先ポートが増えるたび port foward 設定を追加するのもメンドクサイ。
その点、 透過型プロキシだと実際にパケットが飛ぶときのみ通信が行なわれるので、 電池消耗をあまり心配せずに TCP セッションを張りっぱなしにできる。 また、 LAN 内の通信先/宛先ポートが増えても設定変更は不要。 モバイルで LAN 内にアクセスする方法として最適だと思う (便利なのに普及していないのはナゼ?)。
More...