トップ «前の日記(2019-03-05) 最新 編集

2019-03-07 [長年日記]

_ AnyproxyがNode.js製のLocal Proxyとしてなかなかよい

Introduction · AnyProxy

Node.js で動く proxy で

  • https を扱えて(証明書生成もできる)
  • Web UI があって
  • header も body も全部 Node.js で書き換え可能

なやつ。Mitmptoxy の Node.js 版と言えば分かる人は分かると思う。

でまぁ、そんな目新しい話はないんだけど、昔話と今回の狙いを残しておこうと思う。

かつてCocproxyがあった

azu/node-cocproxy: Convention over Configuration Proxy written in Node.js.

いろんなバージョンがある*1が、基本的には

  • ホスト名と同じ名前のディレクトリ、パスを掘ってあげて
  • そこにコンテンツを置いておき
  • proxy を起動し
  • ブラウザの通信にその proxy を利用するように設定

以上を満たすと local に該当リソースがあったら利用し、なければ remote のリソースを取得して返すという動作をしてくれる。これを利用することで例えば開発環境を手元で全部再現しなくても Web サイトのフロントエンドなどだけを準備、改善していくことが可能だった。

もちろん今でも HTTPS になっていないサイトに対しては普通に利用できる。手元でだけ別な CSS を当てるといったことが簡単に行えるので、もし知らなかったという人は試してみると面白いと思う。

いわゆるLocal Proxyのユーザー層は複数ある

Local Proxy という言葉はそこまで定着してるわけでもないんだけど、初出はこの辺かな?

ここまで出来る!LocalProxyベースの開発手法紹介

まぁ本当に便利。

ただこの手の Proxy はフロントエンド開発な人たちとは別にセキュリティ業界の人も重宝していて、どっち方面のツール、情報なのかを意識できるようになっておくと、見つけた記事が何を狙っているものなのかを判断しやすくなってよいと思う。Web のフロントエンド開発を目指して OWASP ZAP とか見つけても欲しい関連情報はなかなか辿れないはず。

HTTPS時代、Local Proxyは不便になった

CocProxy は目的に向かって挙動が整っていたのですぐにローカルでコンテンツを書き換え始めることができてとても便利だったが、最大の泣き所は HTTPS に対応できないことである。

そもそも Secure 通信は Hijack できないのがポイントなわけで、Proxy を挟んで中身を書き換えられると困るわけだけど、開発時にはまさにそれをやりたいという矛盾。

ま、解決策はあって、サーバが自分で証明書を持っておいて、そいつをクライアントに信用させればよい。いわゆるオレオレ証明書である。

これをやるのに Mitmproxy を使っていたこともあるんだけど、Cocproxy のような動作をさせるには自分でスクリプトを追加する必要がある。そのうえ一時期ゆっくりだった開発が active になり、独自に追加するスクリプトで利用する API がゴリゴリ変わってこの手のツールが次々死んでいくという事態になっている。

強くて気の利いたツールにこだわる

自分だけの話ならわざと Mitmproxy の古いバージョンを使うとかいろいろ手はあるんだけど、フロントエンド向けに定番ぽいものがあった方がよいかと思って Node.js 製のものを探していたところ Anyproxy を見つけた。まさに最近の Mitmproxy が実現していることがほぼ再現されていて、かつ独自のスクリプトは JavaScript で書ける。

本当はまさに Cocproxy みたいな気の利いた設計の専用 Proxy で HTTPS 時代に対応できているものがあればそれがいちばんよかったんだけど、結構頑張ってみたけどそういうものを見つけることはできなかった。

ということで次善の手として上に挙げた

  • https を扱えて(証明書生成もできる)
  • Web UI があって
  • header も body も全部 Node.js で書き換え可能

を基準に Anyproxy にした。ケータイに証明書をインストールするには QR コードをパシャっとやれば済む親切設計。これなら openssl 叩けとか言わなくて済む。

また 2019-03 時点で GitHub Star 5000 超えだし、repository の owner は alibaba なので、吹いて飛ぶようなこともないだろう。

OSごとの証明書を信用させる方法の違いに注意

具体的に自分がまさにやらかしたことを書くと、かつてやったことのあった iOS での方法が OS のバージョンアップで変わっていたことに気づかずにだいぶ時間をロスしてしまった。

*1 初出はRubyでその後gem化され、Node.jsもPlackもNginxもある