2011年12月17日土曜日

さくらVPSでOpenBSD (squidの設定)

squidをインストールして設定してみます。

squidはproxyサーバーですが、自分の場合「外出時にiphoneなどで何処かのサイトにアクセスしたいけど、不要な画像とかは表示したくないのでsquidでブロックしちゃうよ。」的な使い方になります。

このようなコンテンツフィルタリングにはsquidGuardなどがありますが、そこまでやる気はない(サーバーの物理メモリも少ないのでプロセスはあまり立ち上げたくない)ので、squidで出来る程度のフィルタリングになります。

設定ポリシーは

  • squidのバージョンは2.7(portsでインストール)
  • squidだけで、コンテンツフィルタリングするぞ。
  • ディスクがもったいないので、コンテンツのキャッシュは無効にします。
  • 外部からのアクセスなので、Proxy認証をかけます。
  • 画像をブロックしたときにエラーページを返すとレイアウトが崩れるのでなんとかする。

インストール

portsでインストールします。

# cd /usr/ports/www/squid/
# make install
# make clean=depends
#

/etc/rc.conf.localの設定

インストールが完了したら、/etc/rc.conf.localに下記の設定を追加します

squid_flags=""
pkg_scripts="postfix saslauthd …… 略 …… courier_imap_ssl squid"


アクセスコントロールの設定

最初にaclの設定をします。この辺はデフォルトの設定をコピペしただけです。

# Recommended minimum configuration:
#
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

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8	    # RFC1918 possible internal network
acl localnet src 172.16.0.0/12	# RFC1918 possible internal network
acl localnet src 192.168.0.0/16	# RFC1918 possible internal network

acl SSL_ports  port 443
acl Safe_ports port 80		# http
acl Safe_ports port 21		# ftp
acl Safe_ports port 443		# https
acl Safe_ports port 70		# gopher
acl Safe_ports port 210		# wais
acl Safe_ports port 1025-65535	# unregistered ports
acl Safe_ports port 280		# http-mgmt
acl Safe_ports port 488		# gss-http
acl Safe_ports port 591		# filemaker
acl Safe_ports port 777		# multiling http
acl CONNECT method CONNECT

ブラックリストの設定とキャッシュの無効化

/etc/squidにコンテンツフィルタリングの設定ファイル、whitelist.txt blacklist.txt blackpath.txtを置く事にします。また全てのアクセスをキャッシュしない設定にします。

# blacklistとwhitelistの設定
acl whitelist url_regex -i     "/etc/squid/whitelist.txt"
acl blacklist url_regex        "/etc/squid/blacklist.txt"
acl blackpath urlpath_regex -i "/etc/squid/blackpath.txt"

# cacheを無効にする
no_cache deny all

squidアクセスの制限設定

aclのblacklist・blackpathで定義したコンテンツはブロックします。aclのwhitelistで定義したコンテンツはブロックしません。

# cachemgrアクセス(キャッシュされたオブジェクト情報へのアクセス)は
# ローカルホストからのみ許可する。
http_access allow manager localhost
http_access deny  manager
# acl名Safe_portsで定義したポート以外へのリクエストを拒否する。
http_access deny !Safe_ports
# SSLポート以外へのCONNECTメソッドのリクエストは拒否する。
http_access deny CONNECT !SSL_ports

# whitelistは許可 と blacklist拒否
http_access allow whitelist
http_access deny  blacklist
http_access deny  blackpath
deny_info http://blackhole.example.com/index.php?url=%s blacklist
deny_info http://blackhole.example.com/index.php?url=%s blackpath

# ローカルホスト ローカルネットからのアクセスは許可する。
http_access allow localnet
http_access allow localhost

画像をブロックするとリンク切れの状態なる問題

blacklistで画像をブロックすると、squidは空白のページを返してきます。するとsafariなどのブラウザは画像のリンクが切れていると判断して、はてなマークのアイコンを表示してしまい画面が見づらくなってしまいます。

画像link切れ

これを回避するために下記の設定を行い、ブロックした場合はhttp://blackhole.example.com/index.phpに飛ばします。index.phpでは引数に指定されたURLにより出力内容を変えてあげます。

deny_info http://blackhole.example.com/index.php?url=%s blacklist
deny_info http://blackhole.example.com/index.php?url=%s blackpath

index.phpは拡張子をみて、それに見合った1dotの白画像を出力するだけの簡単なプログラムです。

<?php
error_reporting(0);
if(preg_match('/\.(jpeg|jpg|jpe)$/',$_GET['url'])){
    $img = file_get_contents('./images/spacer.jpg') ;
    header('Content-type: image/jpeg') ;
    echo $img ;
}
elseif(preg_match('/\.(png)$/',$_GET['url'])){
    $img = file_get_contents('./images/spacer.png') ;
    header('Content-type: image/png') ;
    echo $img ;
}
elseif(preg_match('/\.(gif)$/',$_GET['url'])){
    $img = file_get_contents('./images/spacer.gif') ;
    header('Content-type: image/gif') ;
    echo $img ;
}
else{
    echo "" ;
}
?>

この設定をした後の画面は下記のようになりすっきりします。

画像link切れ対処

認証の設定

外部サイトのproxyなので他人に使用されないように認証をかけます。basic認証だと平文でパスワードが流れてしまうので、Digest認証を使うことにします。

## 認証設定
# digestを使用
auth_param digest program /usr/local/libexec/digest_pw_auth /etc/squid/digpass
# 認証プロセスの数を指定します。
auth_param digest children 5
# ダイジェスト認証の「ユーザ名・パスワード画面」に表示する文字
auth_param digest realm Squid proxy-caching web server
# クライアントエージェントの有効性をチェックする時間を指定します
auth_param digest nonce_garbage_interval 5 minutes
# nonce(臨時・その場限り)の有効性のチェックする時間を指定します
auth_param digest nonce_max_duration 30 minutes
# nonceの使用できる回数を指定します。
auth_param digest nonce_max_count 50
# Squidでnonceのカウンターを1づつ進めていきます。
auth_param digest nonce_strictness on
# このディレクティブはoffにセットされたならnonceのカウントチェックを無効
auth_param digest check_nonce_count off
auth_param digest post_workaround off

# 認証を要求
acl password proxy_auth REQUIRED
# 認証を通ったアクセスは許可
http_access allow password
# そのほかのアクセスはすべて拒否する
http_access deny all

設定値はsquid.confのコメントに書いてあったものをほぼコピーしただけです。但し、auth_param digest check_nonce_countはoffにしておかないと、iOSで認証ダイアログが繰り返し表示されてしまいました。原因を特定するのにえらい苦労しました。IDとパスワードは/etc/squid/digpassに平文でID:PASSWORDの形式で列記してあげれば良いです。

それ以外の設定

ヘッダ情報やキャッシュなどの設定を行います。

# ドットなしのホスト名にローカルなドメイン名を付加します。
append_domain .example.com

# squidが受け付けるhttpのポート番号
http_port 1234

## ヘッダー情報の設定
# 内部 IP アドレスが送られないようにする
forwarded_for off
# Proxyの存在を知らせない
header_access X-Forwarded-For deny all
header_access Cache-Control deny all

## キャッシュの設定
# 複数のsquidサーバで、お互いのキャッシュ情報を参照し、効率的に連携させることができる。
# 無効にするには "0"を設定する。
icp_port 0
# IPキャッシュの数
ipcache_size 5120
cache_mem 32 MB
# キャッシュは無効にしてあるので /dev/nullに設定
cache_dir null /dev/null
maximum_object_size 512 KB
maximum_object_size_in_memory 16 KB

## ログの設定
# ストレージ・マネージャーの活動を記録しない
cache_store_log none
# apache風ログで出力
emulate_httpd_log on
logformat common %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %Hs %<st %Ss:%Sh
access_log /var/squid/logs/access.log common
# クライアントごとの統計を無効
client_db off

設定のチェックと起動

最初に設定した記述が正しいかチェックします。エラーメッセージが出なければ問題なしです。

# /usr/local/sbin/squid -k parse
#

設定に問題無ければキャッシュディレクトリを作成します。今回はキャッシュ無しなのでやらなくても問題ないと思うのですが一応… ディレクトリを作成したら起動させます。

# /usr/local/sbin/squid -z
2011/12/16 00:36:03| Creating Swap Directories
# /etc/rc.d/squid start
squid(ok)
# 

起動したら、ブラウザ側にproxyの設定を行い、接続および認証ができるか確認してみます。


blacklistの作成

blacklistは、頻繁に訪れるサイトの不要な画像やjavascript,iframe等のリンクを抽出して/etc/squid/blacklist.txtに正規表現で記述していきます。同様に不要なパスを/etc/squid/blackpath.txtに正規表現で記述します。

/etc/squid/whitelist.txtにはブロックしたくないコンテンツを記述していきます。特に

deny_info http://blackhole.example.com/index.php?url=%s blacklist
deny_info http://blackhole.example.com/index.php?url=%s blackpath

の設定では、"?url"にブラックリストのURLが入ってくるため、このプログラム自体がブラクックリストにマッチしてしまいフィルタリング処理がループしてしまいます。ですので上記で設定したドメインは必ずwhitelist.txtに指定します。

参考の為にブラックリストを晒しておきます。このリストは俺専用にカスタマズされているので、他の人が使用しても全く効果がないかもしれません。

フィルタリング適応前と適応後

フィルタリング適応前と適応後を比べてみます。比較するページがなんで「発言小町」なんだと言う突っ込みは無しの方向で(笑)

まずは適応前で、全体的に五月蠅い感じで、讀賣らしさが出ていますね。

適応前

そして適応後、素のHTML部分が残ってしまているのが悔しいですが、大分すっきりしました。「小町のiAppを入れろよ」と言ってくる、うざい広告のjavascriptもブロックしているのでイライラせずにブラウズする事が出来るようになりました。

適応後

0 コメント:

コメントを投稿