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

※eucとsjisでそれぞれ同じ内容を保存。

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

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の一覧も簡単に出力できます。
親はログを見るだけで、不健全なサイトを見ようとしたことを察知でき、
その情報を元に子供に正当な 教育 を施すことが可能となるのです。

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

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