SST連載・解説記事

  1. HOMEHOME
  2. SSTコラムSSTコラム
  3. SSTtechlog
  4. 10 Nettyについて勉強して、オリジナルのローカルHTTPプロキシを作ってみました!

(2018年1月19日公開)

SSTtechlog

はじめに

2017年9月-10月頃に、非同期イベント駆動のI/Oライブラリである Netty について勉強する機会がありました。 その時に調査した内容や、実際にNettyを使って作成したローカルHTTPプロキシの紹介をしたいと思います。

調査・検証環境:

  • OS : Windows10Pro 64bit 日本語版
  • JDK 1.8.0_92
  • Netty 4.1.15.Final / 4.0.44.Final

Nettyの調査内容については以下のGitHubリポジトリで公開していますので、詳細はそちらを御覧ください。

JavaのソケットプログラミングとNetty

Javaのソケットプログラミング(特にTCP/IP)の概要と、なぜNettyを使うと便利になるのかについて、図で簡単に紹介します。

初期のJavaではblocking(同期)I/Oを使ったソケットプログラミングしかできませんでした。 サーバ側をMulti Thread にして、acceptしたあとは各クライアントごとのスレッドで処理します。 これにより複数クライアントからの同時接続に対応しています。

blockingI/Oを使ったマルチスレッド型ソケットプログラミングの図

その後 non-blocking な非同期I/Oが使えるようになり、シングルスレッドで複数クライアントからの接続を処理できるようになりました。

non-blockingI/Oを使ったシングルスレッド型ソケットプログラミングの図

しかし、実際に今回シングルスレッドで非同期I/Oを使ったプログラミングを試してみたところ、かなりコードが複雑になることが分かりました。 一つのスレッド内で複数クライアントの通信バッファと通信状態を管理する必要があり、それがコーディングを難しくしている印象を受けました。 そこで non-blocking I/O の複雑さを和らげるためのライブラリが開発されるようになり、Nettyはそうしたライブラリの一つとして(個人の主観ですが)非常にメジャーなものであると思われます。

Nettyを使うことで以下のように低レイヤーのAPIを直接操作する必要が無くなり、プロダクトの本来の機能開発に集中できるようになります。

Nettyを使ったシングルスレッド型ソケットプログラミングの図

実際に blocking/non-blocking I/O で簡単なTCP Echo サーバ/クライアントを作成し、挙動の違いを観察した記事をGitHubのWikiにまとめていますので、詳細はそちらを御覧ください。

オリジナルのローカルHTTPプロキシを作ってみた

NettyにはHTTP用のコンポーネントが含まれているため、比較的簡単に独自のWebサーバを作成することができます。 公式ドキュメントおよびソースコードのクロスリファレンスからサンプルコードを参照できますので、サンプルコードを見ながら少しずつカスタマイズしていくと楽しく学べると思います。

今回はもう一歩踏み込んで、ローカルHTTPプロキシの作成に挑戦してみました。 幸い、NettyをベースにしたHTTPプロキシライブラリ LittleProxy がありました。 LittleProxy 用のMITM処理には lightbody/browsermob-proxyMITMライブラリ を使いました。 これらのライブラリのおかげでアイデア段階から約2日で完成させることができ、Nettyエコシステムの便利さを実感しました。

ローカルHTTPプロキシで何をやらせるか?ですが、特定のホスト・URLパス以下をローカルファイルにマッピングする機能を実装してみました。 ユースケースとしては、WebデザイナやWebアプリ開発者が、本番サイトを参照しつつ、ローカルで編集したCSSやJavaScriptを適用させた時どうなるかを簡単に確認したい、というシーンを想定しています。 プロキシにより「代わりのリソース」に差し替える動きをするので、”alternate” という単語から “alter-proxy” と名付けました。

作成したソースとビルドバイナリ(jarファイル)を以下のGitHubリポジトリで公開していますので、興味のある方は是非お手元にDLして試してみてください。

それではどんな機能か、簡単に紹介していきます。

alter-proxyの紹介

以下がalter-proxyのメイン画面です。HTTPプロキシのポート番号とマッピング設定の一覧が表示されます。

alter-proxyのメイン画面

以下がマッピングの設定画面です。差し替えるリソースの拡張子については明示的に指定するスタイルです。

alter-proxyのマッピング設定画面

では実際にSSTのWebサイトのリソースを差し替えてみます。 以下が本記事作成時点でのSSTのWebサイトです。

本記事作成時点でのSSTのWebサイト画面

ダウンロードツールなどを使ってWebサイトのリソースをダウンロードし、ローカルに展開します。 今回は以下のようにロゴ画像を差し替えてみます。

ロゴ画像差し替えた図

alter-proxy側のマッピング設定で1点注意があります。 デフォルトのマッピング設定では画像ファイル系の拡張子が除外されているので、明示的に追加しないとロゴ画像(.png)を差し替えてくれません。

拡張子のカスタマイズの図

alter-proxyのstartボタンをクリックしてプロキシを起動し、ブラウザのプロキシ設定でalter-proxyを通るようにします(実際はブラウザ -> burp -> alter-proxy としてburpを一段挟んでます)。 ではブラウザキャッシュをクリアしてからアクセスしてみると・・・以下のように無事ロゴ画像が差し替わりました!

ロゴ画像が差し替わった図

まとめ

Nettyを勉強したことでnon-blocking I/Oプログラミングを学ぶことができました。 また、Nettyエコシステムを活用することで簡単ながらもローカルHTTPプロキシを作成することができました。

SSTのサービスであるWAFと脆弱性診断で活用できるかどうか、ですが、いずれもHTTP通信に対して文字列のマッチ処理やDB処理など時間のかかるblocking処理が必須となります。 そのため、今すぐSSTのサービスのコアで活用することは難しいように思われました。 ただし「実験用の簡単なWebサーバを作りたい」「Burpではカバーできないような独自のHTTPプロキシを作りたい」などちょっとしたツールを作るのには便利ですので、実際の現場で活用していければと思います。

なお、実際にalter-proxyを使ってみていただいた感想など筆者まで教えていただければ幸甚です。


文責 : 坂本 昌彦 (研究開発部所属, 社内で使用するWebアプリケーション診断ツールの開発などに従事)

本記事に関するご意見・お問い合わせは坂本までお願いします。

今までのコラム

Webセキュリティをざっくり理解するための3つのMAP

Page Top