アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

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

以前、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圧縮はもとより、画像をJPEGJPEG2000形式に変換して更に削減することが可能です。
サイズを優先するため画質は下がりますが、速度との兼ね合いで我慢出来るところまで下げます。

4・実際の設定


 Internet
    |
 Privoxy
    |
 Ziproxy
    |
  Squid
    |
   PC

のように三段プロキシします。



apt-get install squid ziproxy privoxy

恒例のapt-get。

5・Squid設定
まずは、Squidの設定です。
/etc/squid/squid.conf


# ACLに関する設定
acl all src all
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32
acl localnet src 192.168.0.0/16 # アクセスを許可するIP
acl Safe_ports port 80		# アクセスを許可するポート
acl Safe_ports port 8080
acl SSL_ports port 443		# https
acl purge method PURGE
acl CONNECT method CONNECT

# アクセス制限
http_access allow manager localhost
http_access deny manager

http_access allow purge localhost
http_access deny purge

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

http_access allow localnet
http_access allow localhost
http_access deny all

#icp_access allow localnet
#icp_access deny all

# 受付ポート
http_port 3128

# 上位プロキシサーバ(今回はziproxy)
cache_peer localhost parent 8080 7 no-query
never_direct allow all

# 表示用ホスト名
visible_hostname hogehost

# forwarded_for、viaヘッダを送信しない
forwarded_for off
via off

# キャッシュに使用するメモリ量
cache_mem 256 MB

# ローカルディスクに保存設定
# cache_dir ufs パス サイズ(MB) ディレクトリ数 ←の中につくるサブディレクトリ数
cache_dir ufs /var/spool/squid 512 16 256

# キャッシュ設定※1
refresh_pattern -i (jpg|jpeg|png|gif|css|js)            1440     100%     10000 override-expire
refresh_pattern -i (html|htm)   1440	100%	10000 override-expire
refresh_pattern .               0     0%     0

# その他細々設定
acl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9]
upgrade_http0.9 deny shoutcast
acl apache rep_header Server ^Apache
broken_vary_encoding allow apache
extension_methods REPORT MERGE MKACTIVITY CHECKOUT
hosts_file /etc/hosts
coredump_dir /var/spool/squid
access_log /var/log/squid/access.log squid
hierarchy_stoplist cgi-bin ?



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


6・Ziproxy設定

/etc/ziproxy/ziproxy.conf


AccessLog = "/var/log/ziproxy/access.log"
# 次のプロキシ設定(今回はprivoxy)
NextProxy="127.0.0.1"
NextPort=8118

TransparentProxy = true
UseContentLength = false
ImageQuality = {30,25,25,20}

NextProxy、NextPort以外はデフォルトです。画質もまあまあなので。

7・Privoxy設定

/etc/privoxy/user.action


## デフォルトの設定
{{alias}}
+crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
 allow-all-cookies  = -crunch-all-cookies -session-cookies-only -filter{content-cookies}
 allow-popups       = -filter{all-popups} -filter{unsolicited-popups}
+block-as-image     = +block{Blocked image request.} +handle-as-image
-block-as-image     = -block

fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -prevent-compression
shop        = -crunch-all-cookies allow-popups

myfilters   = +filter{html-annoyances} +filter{js-annoyances} +filter{all-popups}\
              +filter{webbugs} +filter{banners-by-size}

allow-ads   = -block -filter{banners-by-size} -filter{banners-by-link}

{ allow-all-cookies }


## 以下、追記の設定 ##

# 汎用HTML書き換え用
# fixedでついてくる鬱陶しいタグ除去とか
# 不要コンテンツブロックとか
{+filter{word_filter}}
.

# 日本語で鬱陶しい単語を除去
# 3種類同じ内容をエンコード別に用意
{+filter{word_filter_utf8}}
.
{+filter{word_filter_sjis}}
.
{+filter{word_filter_euc}}
.

# サイトごとの特別なフィルタいくつか
# サイトを名指しするのは悪い気がするので隠します。
{+filter{******_filter}}
.*******.jp

{+filter{******_filter}}
.*******.jp

{+filter{******_filter}}
.*******.jp

# 特定のサイトを見る場合はUAを偽装
{+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}}
*****.jp
*******.jp
*********.jp

# 都営バスのサイト、Operaで見ると携帯扱いになるので、IEに偽装
{+hide-user-agent{Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)}}
tobus.jp



/etc/privoxy/user.filter


FILTER: word_filter word_filter
# 特定のドメインへのリンクがあれば非表示
s|http://********.jp/|" style="display: none;" "|g
s|http://*******.jp/|" style="display: none;" "|g

# iframeはブロック
s|<iframe.*?</iframe>|<div style="border: solid 1px #F00;">deleted by privoxy</div>|g

# その他要らないワードは消す
s|*******||g

# 個別サイトフィルタ
FILTER: *****_filter *****_filter
s|.....|******|g

/etc/privoxy/user.action_*については恥ずかしいので省略

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

8・Privoxy追加設定

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

/etc/privoxy/user.action


# 10/1追記
# 動画・音楽はダウンロード禁止

## タグを作成して、content-typeを使用して判別出来るようにする
{+server-header-tagger{content-type}}
.

## blockでは、タグを見て判別
{+block}
#TAG:.*application/.*
TAG:.*audio/.*
TAG:.*video/.*


/etc/privoxy/user.filter


# タグ設定 Content-Typeの中身取得
SERVER-HEADER-TAGGER: content-type
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・最終手段
>>BOXNC
$ sudo halt

Privoxyで透過型書き換えプロキシを作ってみた

今回は会社や家庭で便利に使えるプロキシ Privoxy についてまとめてみようと思います。

1・プロキシ(Proxy)とは


直訳すると「代理」
書いたままの意味で、ある通信をする際にデータを直接提供元に取りに行くのではなく、別の代理サーバを経由して取りに行くようにできるシステムです。
プロキシサーバはそれを提供しているサーバで、一般的にプロキシといえばHTTPプロキシを指すことが多い。
今回の記事もHTTPプロキシの意で使用します。

2・Proxyの利点


64Kbpsのモデムで通信していた時代、全く更新がないページをダウンロードするのは無駄以外の何者でもないので、一度見たページはプロキシサーバを使用してキャッシュして高速化という使い方もありましたが、最近は回線が太くなりプロキシを経由するボトルネックの方が大きくなって来ました。
そこで、今導入する利点を挙げて見ました。(自分が思いつく限り)

・フィルタリング
 IPレイヤではできない、HTMLの内容を見て判定。
 今回の記事で解説。
・通信の圧縮
 ziproxyあたりを入れて、通信を圧縮したり画像の画質を下げて軽くする。
 スマートフォンでこのプロキシを使用して快適に見るとか出来ます。
 OperaTurboもこれを使用。
・匿名性の確保(?)
 こちらもだいぶ昔から言われている利点で、サーバ側の設定によってはクライアントの情報をすべて隠蔽できる。(サーバ側のものになる)
 ターゲットサイトの管理者レベルから見たら何もわからないが、「サーバのログを押収する権限のある機関」には多分無力なので、悪いことはしないように。

上記3件はクライアントが使いたいサーバを選択して機能を享受しますが、サーバ側(データ提供側)で使用されるプロキシがあります。
・リバースプロキシ
クライアントからは普通のWEBサーバとして振る舞います。
複数のWEBサーバにロードバランスするとか、URL書き換えたり、静的ファイルをキャッシュなどをして、サーバ側の負荷対策に貢献します。
このブログ見ている人だと、こちらのほうが馴染み深いんではないかと思います。


なお、どのタイプにも言えることですが、
サーバを公開する際には、セキュリティをしっかり設定してください。
千客万来にしておくと不正中継されて、悪用される可能性があります。


2・Privoxyとは


HTTPプロキシの一種。
名前の通り(?)プライバシを確保する機能が乗っています。
Cookieを無効化したり、サーバへ送るUAなどの環境変数を偽装したり、
HTMLの内容自体の書き換えも出来るので、よく広告ブロックに使用されます。
広告をブロックするなんて無料サイトの根底を揺るがしかねないので、
そんなけしからん機能使っちゃダメですよね。
もちろん、フィルタをかけ過ぎると重くなるので注意してください。

3・インストール





apt-get install privoxy

で入ります。

Redhat系でも、多分yumで入るのではないかと思います。

なお、デフォルトの設定で一般的な広告のサイズの画像やドメインをブロックしているので、設定変更は必要です。

4・設定


/etc/privoxy/にまとまっており、
/etc/privoxy/config が全てです。ここで各種く設定や別ファイルの読み込みを指定します。

通信の書き換えに使用する設定ファイルは
なんとか.action
なんとか.filter
の2種類があり、
〜.actionで適用するURL、〜.filterで実際に適用する内容を定義します。

自分の場合は、先にziproxyを経由するので、待受アドレスを下記のようにローカル限定。
どこからでも待ち受ける場合は0.0.0.0を書いてください。


listen-address  127.0.0.1:8118


フィルタは、全角文字の書き換えをしたいので下記のようにascii+各文字コード分を独自に定義しました。


filterfile user.filter
filterfile user.utf8.filter
filterfile user.sjis.filter
filterfile user.euc.filter


フィルタ本体の設定です。
まずは、user.actionに適用したいドメインを部分一致で列挙します。


{+filter{word_filter}}
.

{+filter{hogehoge_example_com_filter}}
hogehoge.example.com


最初の"+"はフィルタを追加、"-"を書けば、そのフィルタを外す命令です。
filterの次は、適用するフィルタ名です。(〜.filterで定義されているもの)

次にuser.filterに実行したいperl方式の正規表現を書きます。
いくつか指定していますが、
例えばWordPressで、「Back To Top」をピンク色で表示するプラグインがありますが、iPhone使いなので特にいりません。
スクロールするたびにフェードインして出てきて非常に鬱陶しいので、idを消して無効化してます。



{+filter{word_filter}}
s|takeMeUpContainer||g


その他、自分には不要なjsとか、cssとか画像とかを削除しておく快適になりますが、必要なものまで消してしまう可能性があるのでご注意ください。
その状態な事を忘れて、アプリケーションの開発やテストをすると訳のわからないことでハマるので(ry

なお、日本語をフィルタする場合には、utf8,euc,sjisでそれぞれ同じ内容を書いて指定すれば多分動きます。

user.action


{+filter{word_filter_utf8}}
.
{+filter{word_filter_sjis}}
.
{+filter{word_filter_euc}}
.


user.filter


{+filter{word_filter_utf8}}
s|.*ほげ.*|あぼーん|g

eucsjisでそれぞれ同じ内容を保存。

"ほげ"はサンプルですが、基本的に罵り合いか下品な広告くらいにしか使われない言葉を書いておくと便利です。
さすがにそのまま消すと文脈がよくわからなくなるので、あぼーんに変えてます。
どこかの掲示板見る場合には便利ですね。


4・透過型プロキシにする



通常、プロキシはブラウザにて指定しますが、ゲートウェイtcp通信をフックして強制的にプロキシを使用させる方法が透過型プロキシです。

Linuxでやるのは簡単で、
まずはprivoxyのconfigで、accept-intercepted-requestsを1にします。
(プロキシ特有の通信でなくても処理出来る機能を有効)



accept-intercepted-requests 1


あとはiptablesで、どこかの80へのアクセスが来たら、そのままプロキシサーバへ渡すと書けばOKです。


iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.1.2:8080



ここまでで、Privoxyとサーバ側の解説は完了です。

5・フィルタ例(おまけ)



自宅の環境では使っていませんが、こんなことフィルタすると捗るかもしれない事を書いてみます。

■会社編
基本的にサボり防止とか流出防止とか。
ただし、アクセス禁止しすぎると何も調べられなくなるので注意。

youtube,niconico,yourfilehostなどへのアクセスは、「仕事しろページ」へリダイレクト
 または、「R18」とかの文字列を含んでいたらリダイレクト。

2ch.netへのアクセス禁止
 技術系スレならOKだが、雑談系には禁止。
 s|.*以下、名無しにかわりましてVIPがお送りします.*||名前欄デフォルトを追記しておく。

・まとめ系アクセス禁止
 上記と同じ。

・特定のアドレスに行く時には携帯のUAに偽装
 いちいちブラウザでUA切り替えなくても便利。

その他、いちいちログが残るので監査的なことにも使用できます。
フィルタリングするにもサーバの性能が必要なので、あまり複雑なことはできないかと思います。

個人的には、こんな細かいことで縛るよりも自由にした方がいいかと思いますが。


■自宅編
※以下は私個人の独断と偏見で書いています。あくまでも個人の意見です。

フィルタリングは教育所良くないサイト から 子どもたち を守るのに使えます。
子供はいませんが、純粋無垢な 子どもたち の事を考えてみました。

プロバイダや、ブロードバンドルータにもフィルタリングサービスはありますが、厳密に指定できないので不便。
そこで、上記のフィルタリングを緩くして、カバーしきれないところをブロックすると便利。

仮に過剰にブロックしても "健全なサイトと証明できれば外すだけ" なので問題ありません。

子どもたち に不要な単語を発見したらページを真っ白にしてしまいましょう。
※公共の場にそぐわない単語があるため、一部伏字にしています。


s|.*.エ□.*||gs
s|.*$ex*||igs
(中略)
s|.*竿.*||gs
s|.*抜.*||gs
s|.*糸.*||gs
s|.*果実.*||gs
s|.*花びら.*||gs
s|.*露.*||gs
s|.*林.*||gs
s|.*森.*||gs
s|.*丘.*||gs


また、暴力や麻薬関係にも制限を入れましょう。


s|.*酒.*||gs
s|.*タバコ.*||gs
s|.*ドラッグ.*||gs
s|.*調合.*||gs
s|.*ケンカ.*||gs
s|.*暴力.*||gs
s|.*暴走.*||gs
s|.*改造.*||gs
s|.*チューニング.*||gs
s|.*クラブ.*||gs
s|.*ダンス.*||gs
s|.*パフォーマンス.*||gs


実に不健全で子どもたちの教育に悪そうな単語が揃いました。
この調子で単語やパターンを増やしていけばいいと思います。

--

本当はフィルタなんか使わないほうがいいのですが、
情報を公開する悪い人間がいる以上、フィルタは必要なのです。

また、プロキシを入れることにより、見ようとしたURLの一覧も簡単に出力できます。
親はログを見るだけで、不健全なサイトを見ようとしたことを察知でき、
その情報を元に子供に正当な 教育 を施すことが可能となるのです。

・そもそも単語が汎用的すぎるって?
子どもたちを守るためなので仕方のないことなので、仕方のないことです。

もし、フィルタに引っかかったら、
とりあえず子供を連れてきて事情を聞いて"正当性を証明"させればいいだけなのです。
証明できなければ"教育"を施し、
過剰にフィルタリングしていれば、"正当な手続き"で解除すればいいだけですからね。