2013年3月25日月曜日

ServersMan@VPS(Debian32bit)で圧縮プロキシサーバ

AndroidのChromeブラウザが最新ベータでSPDYプロキシサーバに対応したそうです。
"chrome://flags"から"Experimental Data Compression Proxy"を有効にすればいいみたいです。
残念ながらChromeはAndroid 4.0以降にしか対応していないため、
私には何の影響もありません。
というか今までSPDYに対応してなかったの?とか思ったのですが、
本家のサイトを確認するとちょっと意味が違っているようで、
どうやらGoogleで用意したプロキシサーバとChromeの間をSPDYでつなぎ、
SPDYに対応していないウェブサイトへのアクセスをプロキシにさせることで、
端末からの体感速度を上げるような仕組みを新たに作ったようです。
要は圧縮プロキシですね。
最初に記事を読んだとき、SPDYそのものがhttps上で動作しているのに
httpsサイトに対応していないというのはどういうことかと疑問だったのですが、
中身がプロキシサービスだということで納得です。

話は変わりますが、私はServersMan@VPS(Debian32bit)上で
プロキシサーバをだいぶ前から動かしています。
主な用途はIPv6界への入り口だったりします。
まあ世の中の回線が太くなっている昨今、
そこがボトルネックになりかえって遅くなりかねません。

私の場合、IIJmioの128kbps(常時200kbpsは出てますけど)制限の回線があるので、
もしかすると役に立つかもと思いつつも、
モバイルで使っているAndroid(<=3.0)ではプロキシが設定できないという
悲惨な仕様により試そうとも思いませんでした。

ただ、数ヶ月前に手に入れたiPhone4Sでは
無線LANのアクセスポイント毎にプロキシが設定可能なので、
低速回線経由時のために圧縮プロキシあってもいいかなーと思いつつも、
よほどの緊急事態(実店舗で売ってる物がネット通販でいくらで売っているかを確認とか?)
でもない限り3G回線でのネットサーフィンはしないので、手をつけていませんでした。
設定めんどくさいですし。

そんな感じの中で、SDPYプロキシの件に触発され重い腰を上げることに成功しました。
まあこれがちょっとした地獄の始まりだったのですが…

さて、プロキシといえば私もよく使うsquidなのですが、
squidには圧縮プロキシにはできません(私の思い込み?)。
で、圧縮プロキシといえばDelegateです。
ということで早速ServersMan@VPS(Debian32bit)にインストールです。
画像圧縮のためimagemagickもインストールします。
以下を実行します。
# apt-get install imagemagick
# cd /usr/local/src
# wget http://www.delegate.org/anonftp/DeleGate/delegate9.9.8-pre20.tar.gz
# tar zxf delegate9.9.8-pre20.tar.gz
# cd delegate9.9.8-pre20
# make
1@1
y
# cd /usr/local/sbin
# ln -s /usr/local/src/delegate9.9.8-pre20/src/delegated delegated
# cd /etc
# cp /usr/local/src/delegate9.9.8-pre20/src/delegated.conf ./
設定ファイル"/etc/delegated.conf"の内容に以下を追加します。
REMITTABLE=+,http
PERMIT="*:*:*"
とりあえず動くようになったので起動してみます。
TCPのポート番号を指定して起動するのですが、
一般的に使われる8080や8000が私の環境ではすでに埋まっているので
8001を使うことにし、以下を実行すると、nobodyユーザで起動します。
# delegated -P8001 +=/etc/delegated.conf
ちなみにこのコマンドを一般化すると
# delegated -P<ポート番号> +=<設定ファイル(フルパス)>
となります。
ところで、再起動する(設定ファイルの変更反映等)場合は'-r'オプションをつけて
# delegated -P8001 +=/etc/delegated.conf -r
のようにし、停止する場合は'-Fkill'オプションをつけて
# delegated -P8001 +=/etc/delegated.conf -Fkill
を実行します。
ここまでの作業でプロキシは動作するようになります。
ウェブブラウザ側を適切に設定すればプロキシ経由でのネットサーフィンが可能です。
あとは自動起動のために、起動スクリプト"/etc/init.d/delegted"を
#! /bin/sh

### BEGIN INIT INFO
# Provides:             delegated
# Required-Start:    $local_fs $network
# Required-Stop:     $local_fs $network
# Should-Start:      $named
# Should-Stop:       $named
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description:    Delegate
### END INIT INFO

case "$1" in
  start)
        /usr/local/sbin/delegated -P8001 +=/etc/delegated.conf
        ;;
  stop)
        /usr/local/sbin/delegated -P8001 +=/etc/delegated.conf -Fkill
        ;;
  restart|reload)
        /usr/local/sbin/delegated -P8001 +=/etc/delegated.conf -r
        ;;
  *)
        echo "Usage: /etc/init.d/delegated {start|stop|reload|restart}"
        exit 1
esac
exit 0
のように作成して、以下を実行しておけばよいでしょう。
# chown root:root /etc/init.d/delegted
# chmod 755 /etc/init.d/delegted
# update-rc.d delegated defaults

ところで、今回は圧縮プロキシに仕立てることが目的ですので、
設定ファイル"/etc/delegated.conf"にさらに以下の行を追加します。
HTTPCONF=acc-encoding:-thrugzip
HTTPCONF=gen-encoding:gzip
これでHTMLドキュメントがプロキシ-ウェブブラウザ間でgzipによる圧縮転送されます。
同様に画像ファイルを粗くしてサイズを小さくするには、
設定ファイル"/etc/delegated.conf"に
FTOCL=/etc/delegated.cfi
を追加した上で、設定ファイル"/etc/delegated.cfi"の内容を以下のようにします。
#!cfi
Content-Type: image/jpeg
Output/Content-Type: image/jpeg
Filter: convert -quality 30 - -
--
Content-Type: image/png
Output/Content-Type: image/png
Filter: convert -quality 30 - -
--
Content-Type: image/bmp
Output/Content-Type: image/jpeg
Filter: convert -quality 30 - jpeg:-
jpeg画像とpng画像はエンコードパラメータの調整で粗くしてサイズを小さくし、
bmp画像(一般的には無圧縮)はjpegに変換して小さくしています。
gif画像についてはもともと256色までしかサポートしないことを前提にデータ圧縮してあり、
新ためてjpeg等に変換したところで大した効果が期待できないこと、
インターネット上ではgif画像はアイコンのような用途で使われることが多く、
もともと比較的サイズ(ファイルサイズ、ピクセルサイズ)が小さいこと、
バナーなどでよく見かけるアニメーション画像は基本的にgifなことを鑑み
そのままスルーさせています。
なお'--'で区切れば画像の種類を追加できますし、
Filterフィールドの内容はコマンドそのもので、
標準入力で変換元ファイル、標準出力で変換後ファイルを扱う書式にしておけば動きます。
なお、圧縮プロキシの効果は絶大で、ある速度計測サイトでは
160kbpsが360kbpsぐらいにアップしました。
いろいろ試しているとコンスタントに2~2.5倍ぐらいにはなっているようです。
体感的には…速くなったような気もしますが、気のせいのような気もします。

実際にdelegatedを動作させてみて困ったのは、
ウェブブラウザがページを開くたびに子プロセスが生成されるため、
同時起動プロセス数の制限が厳しいServersMan@VPSで、
それでなくてもプロセスが多い私の環境ではすぐに上限に達して
ページが開けなくなってしまいます。
一応の対処として設定ファイル"/etc/delegated.conf"の
もともとの"TIMEOUT"を削除した上で以下の行を追加しています。
MAXIMA=delegated:16
TIMEOUT=io:10
HTTPCONF=max-ckapch:1
ただ、画像がたくさん貼り付けてあるようなサイトを開こうとしたときに開けなかったり、
下記のプロキシ認証を設定してiPhone4Sからアクセスしたときに
プロキシ認証用のダイアログが表示されまくったりします。
この辺はもう割り切るしかありません。

次は認証です。VPS上で常時動作しているので勝手に使われるようでは困ります。
が、ここで大きくはまってしまいました。
まずは正解からです。
なお、プロキシサーバがインターネット上にあるので、
basic認証だと非SSL時に認識可能な状態で認証情報がだだ漏れするため、
digest認証を採用しています。
一応wiresharkでパケットキャプチャして正しく動作していることは確認しています。
まずは設定ファイル"/etc/delegated.conf"に以下の行を追加します。
SERVER=http
AUTH=proxy:pauth
AUTHORIZER=-dgauth
CRYPT=pass:<認証用データ保管用暗号キー(適当な文字列)>
これでdelegatedを再起動させればユーザ認証がかかるようになります。
で、そのユーザ登録は以下を実行することで可能です。
# delegated -Fauth -a <ユーザ名>:<パスワード> -dgauth CRYPT=pass:<認証用データ保管用暗号キー("/etc/delegated.conf"で設定したもの)>
何人分でも作れ、'-a'オプションの代わりに'-d'を使うことでユーザの削除ができます。
最初の1ユーザについては気にする必要はありませんが、
二人目以降はその前に設定した[認証用データ保管用暗号キー]を正しく入力する必要があります。
もし忘れてしまったら、
"/var/spool/delegate-nobody/adm/authorizer/-dgauth/"ディレクトリにある
ファイルを全部消して、最初からユーザを作りなおすことになります。

ここからは裏話になりますが、設定を試行錯誤していく中で何度かトラブルに見舞われました。
そのなかで認証を設定する際には大いにはまりました。
認証をオフ("AUTHORIZER=-dgauth"をコメントアウト)した場合には問題ないのに、
オンにするとdelegatedからTCPのRSTをくらい接続できません。
それもTCPのSYNには成功しているのに、
ウェブブラウザからのHTTPリクエストを受け取るとRSTされるのです。
"LOGFILE"でログを吐き出させたり、'-d'オプションつけてみたり、
通信パケットをみたりしても原因がつかめず、
最後はソースを見なきゃいけないかと覚悟もしかけたのですが、
何気なくやったちょっとしたことで解決してしまいました。
それは設定ファイルへの"SERVER=http"の追加です。
まあ"SERVER=http"は当然入れるべき設定項目といってもよいものの、
認証なしのときはなくても動いていたので入れていなかったのですが、
なぜか認証ありのときは必須になっていました。
単純にプログラムの都合でそうなってしまっただけでしょうが、
これでかなりの時間を無駄にしました。
ということで皆さんが同じところではまらないよう公開しておきます。

0 件のコメント:

コメントを投稿