Asial Blog

Recruit! Asialで一緒に働きませんか?

Privoxy + Ziproxy + Squidで高速フィルタリングサーバを作ってみた

カテゴリ :
バックエンド(インフラ)
タグ :
Tech
Squid
Privoxy
Ziproxy
お手上げ!
以前、Privoxyを使ったネタを書きました。
複雑な書き換え処理が出来るPrivoxyですが、その分オーバヘッドが発生します。
今回は、Ziproxyで通信量を削減し、Squidをでキャッシュさせることにより高速化を目指します。

なお、Ziproxyについては高速回線ではあまり必要無いですが、外出先でemobileを使用して作業をするときに、圧縮プロキシを使用出来ると便利なので導入しました。

1・Privoxyとは?
HTTP通信の内容を書き換えることが出来るプロキシサーバです。
こちらの記事を参照してください http://blog.asial.co.jp/1008

2・Squidとは
言わずとしれたプロキシサーバです。高機能なのでいろいろなことが出来ます。
このブログをご覧になっている方々の場合、リバプロとして使ったことある人の方が多いのかもしれません。

便利なキャッシュ機構を持っているので、今回はそれを使用して色々とキャッシュします。

3・Ziproxyとは?
名前の通り、Zipするproxyです。

HTTPでは通信をgzip圧縮することが出来、HTMLやCSSなどの場合は、CPUを少し使ってでも圧縮して流した方が効率がよくなります。
サーバ側とクライアント側がどちらも対応していれば利用できるので、通信量を削減とレスポンス時間の低減をしたい時に使用すると効果があります。
なお、最近のPCやスマフォなら大抵対応していると思いますので、Webサーバではapacheならmod_deflate、nginxならgzipオプションを有効にしてやれば使用できます。

さて、このZiproxyでは、上述のgzip圧縮はもとより、画像をJPEGやJPEG2000形式に変換して更に削減することが可能です。
サイズを優先するため画質は下がりますが、速度との兼ね合いで我慢出来るところまで下げます。

4・実際の設定
  1.  Internet
  2.     |
  3.  Privoxy
  4.     |
  5.  Ziproxy
  6.     |
  7.   Squid
  8.     |
  9.    PC
のように三段プロキシします。

  1. apt-get install squid ziproxy privoxy
恒例のapt-get。

5・Squid設定
まずは、Squidの設定です。
/etc/squid/squid.conf
  1. # ACLに関する設定
  2. acl all src all
  3. acl manager proto cache_object
  4. acl localhost src 127.0.0.1/32
  5. acl to_localhost dst 127.0.0.0/8 0.0.0.0/32
  6. acl localnet src 192.168.0.0/16 # アクセスを許可するIP
  7. acl Safe_ports port 80 # アクセスを許可するポート
  8. acl Safe_ports port 8080
  9. acl SSL_ports port 443 # https
  10. acl purge method PURGE
  11. acl CONNECT method CONNECT
  12. # アクセス制限
  13. http_access allow manager localhost
  14. http_access deny manager
  15. http_access allow purge localhost
  16. http_access deny purge
  17. http_access deny !Safe_ports
  18. http_access deny CONNECT !SSL_ports
  19. http_access allow localnet
  20. http_access allow localhost
  21. http_access deny all
  22. #icp_access allow localnet
  23. #icp_access deny all
  24. # 受付ポート
  25. http_port 3128
  26. # 上位プロキシサーバ(今回はziproxy)
  27. cache_peer localhost parent 8080 7 no-query
  28. never_direct allow all
  29. # 表示用ホスト名
  30. visible_hostname hogehost
  31. # forwarded_for、viaヘッダを送信しない
  32. forwarded_for off
  33. via off
  34. # キャッシュに使用するメモリ量
  35. cache_mem 256 MB
  36. # ローカルディスクに保存設定
  37. # cache_dir ufs パス サイズ(MB) ディレクトリ数 ←の中につくるサブディレクトリ数
  38. cache_dir ufs /var/spool/squid 512 16 256
  39. # キャッシュ設定※1
  40. refresh_pattern -i (jpg|jpeg|png|gif|css|js)            1440     100%     10000 override-expire
  41. refresh_pattern -i (html|htm)   1440 100% 10000 override-expire
  42. refresh_pattern .               0     0%     0
  43. # その他細々設定
  44. acl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9]
  45. upgrade_http0.9 deny shoutcast
  46. acl apache rep_header Server ^Apache
  47. broken_vary_encoding allow apache
  48. extension_methods REPORT MERGE MKACTIVITY CHECKOUT
  49. hosts_file /etc/hosts
  50. coredump_dir /var/spool/squid
  51. access_log /var/log/squid/access.log squid
  52. hierarchy_stoplist cgi-bin ?

※1 自分で書くよりもわかりやすい記事があるので、こちらご覧ください。
http://sourceforge.jp/magazine/08/11/26/019236/2


6・Ziproxy設定

/etc/ziproxy/ziproxy.conf
  1. AccessLog = "/var/log/ziproxy/access.log"
  2. # 次のプロキシ設定(今回はprivoxy)
  3. NextProxy="127.0.0.1"
  4. NextPort=8118
  5. TransparentProxy = true
  6. UseContentLength = false
  7. ImageQuality = {30,25,25,20}
NextProxy、NextPort以外はデフォルトです。画質もまあまあなので。

7・Privoxy設定

/etc/privoxy/user.action
  1. ## デフォルトの設定
  2. {{alias}}
  3. +crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
  4. -crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
  5.  allow-all-cookies  = -crunch-all-cookies -session-cookies-only -filter{content-cookies}
  6.  allow-popups       = -filter{all-popups} -filter{unsolicited-popups}
  7. +block-as-image     = +block{Blocked image request.} +handle-as-image
  8. -block-as-image     = -block
  9. fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -prevent-compression
  10. shop        = -crunch-all-cookies allow-popups
  11. myfilters   = +filter{html-annoyances} +filter{js-annoyances} +filter{all-popups}\
  12.               +filter{webbugs} +filter{banners-by-size}
  13. allow-ads   = -block -filter{banners-by-size} -filter{banners-by-link}
  14. { allow-all-cookies }
  15. ## 以下、追記の設定 ##
  16. # 汎用HTML書き換え用
  17. # fixedでついてくる鬱陶しいタグ除去とか
  18. # 不要コンテンツブロックとか
  19. {+filter{word_filter}}
  20. .
  21. # 日本語で鬱陶しい単語を除去
  22. # 3種類同じ内容をエンコード別に用意
  23. {+filter{word_filter_utf8}}
  24. .
  25. {+filter{word_filter_sjis}}
  26. .
  27. {+filter{word_filter_euc}}
  28. .
  29. # サイトごとの特別なフィルタいくつか
  30. # サイトを名指しするのは悪い気がするので隠します。
  31. {+filter{******_filter}}
  32. .*******.jp
  33. {+filter{******_filter}}
  34. .*******.jp
  35. {+filter{******_filter}}
  36. .*******.jp
  37. # 特定のサイトを見る場合はUAを偽装
  38. {+hide-user-agent{Mozilla/5.0 (iPhone; U; CPU iPhone OS 2_0 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5A347 Safari/525.20}}
  39. *****.jp
  40. *******.jp
  41. *********.jp
  42. # 都営バスのサイト、Operaで見ると携帯扱いになるので、IEに偽装
  43. {+hide-user-agent{Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)}}
  44. tobus.jp

/etc/privoxy/user.filter
  1. FILTER: word_filter word_filter
  2. # 特定のドメインへのリンクがあれば非表示
  3. s|http://********.jp/|" style="display: none;" "|g
  4. s|http://*******.jp/|" style="display: none;" "|g
  5. # iframeはブロック
  6. s|<iframe.*?</iframe>|<div style="border: solid 1px #F00;">deleted by privoxy</div>|g
  7. # その他要らないワードは消す
  8. s|*******||g
  9. # 個別サイトフィルタ
  10. FILTER: *****_filter *****_filter
  11. s|.....|******|g
/etc/privoxy/user.action_*については恥ずかしいので省略

以上。長い割に大した内容書いてないですね。
会社のブログなので細かいこと書きにくいです。

8・Privoxy追加設定

Content-Typeを見てフィルタを設定できたので、試しに書いてみました。

/etc/privoxy/user.action
  1. # 10/1追記
  2. # 動画・音楽はダウンロード禁止
  3. ## タグを作成して、content-typeを使用して判別出来るようにする
  4. {+server-header-tagger{content-type}}
  5. .
  6. ## blockでは、タグを見て判別
  7. {+block}
  8. #TAG:.*application/.*
  9. TAG:.*audio/.*
  10. TAG:.*video/.*

/etc/privoxy/user.filter
  1. # タグ設定 Content-Typeの中身取得
  2. SERVER-HEADER-TAGGER: content-type
  3. s|^Content-Type:\s*([^;]+).*|$1|i

application/.* だとflashとかjsなどの余計な物もブロックするので
application/ogg などと指定する必要があるので、とりあえずaudioとvideoのみ。

9・使用感
さすがキャッシュ。
JSやCSS、画像をキャッシュしているので圧倒的です。
体感は3、4倍は高速化している気がします。

ただし、一応no-cacheをつけてリロードすれば全部更新するはずですが、
表示やシステムがおかしくなる可能性を考えてないと、訳のわからないハマり方します。

参考までにabとってみました。

ab -X 192.168.xxx.xxx:8080 -n 100 -c 100 "http://xxxxxxxxxx.com/path/to/file.png"
Requests per second: 9.20 [#/sec] (mean)
Requests per second: 10.86 [#/sec] (mean)
Requests per second: 5.84 [#/sec] (mean)
Requests per second: 7.66 [#/sec] (mean)
Requests per second: 8.51 [#/sec] (mean)

ab -X 192.168.xxx.xxx:3128 -n 100 -c 100 "http://xxxxxxxxxx.com/path/to/file.png"
Requests per second: 10.89 [#/sec] (mean)
Requests per second: 44.51 [#/sec] (mean)
Requests per second: 52.89 [#/sec] (mean)
Requests per second: 69.05 [#/sec] (mean)
Requests per second: 88.47 [#/sec] (mean)

まあ、最初以外はキャッシュが効いているので圧倒的に早いです。


10・おまけ
本当は、最近ニュースで少しだけ話題になった、
「ウィルス(?)が掲示板に変なこと書き込むことを禁止する」
ことを防止する設定も書きたかったのですが、

・送信データを強制的に置換するのは、パターンがありすぎて却下。
・掲示板のブラックリストを作るのも現実的でないので却下。

もう、POSTを原則禁止にして、GETのパラメータを全部取って、ホワイトリスト方式で許可していく方法しか思いつかない。

PCなら最悪上記のような対策できますが、
ネイティブアプリや、
セキュリティホールを利用されるなどして
スマートフォンが"感染"したら端末から直接ネットなので対策不能ですね。

あれか、ストールマンじゃないが持たない事しか対策方法ないのか。

11・おまけ2
8番の設定は、ダウンロード刑罰化に対する対策を書いてみました。
え?そんな対策しなくても、ストリーミングなら合法じゃないかと?

IP通信齧ったことのある人ならわかると思いますが、通信自体で見分ける方法なんて無いです。ストリーミングもダウンロードの一種です。
まあ、私は判別出来ませんが、
日本の司法は世界一優秀なので、すごく簡単に判別するんでしょうね。


この設定と、しっかり透過プロキシの設定すれば、意図しないダウンロードは避けられます。多分。
content-typeをtext/htmlにされたりすれば意味無いですが。
あと、httpsだったり。

とりあえず、Youtubeで「猫」と検索して一番上に出た"かわいい猫動画"は見られなくできました。
まさに気分は「ねこーねこー」です。

前項にしても、ホワイトリストしか手がないのか。それか、VPNかまたは某玉ねぎ網か。

12・最終手段
  1. $ sudo halt