Kozupon.com    
 
 squirmによるコンテンツフィルタの作成!


インターネット上のコンテンツ観覧に規制を掛けること自体に、俺は興味がない。しかし、コンテンツに規制を掛けるツールであるコンテンツフィルタの、その構造及びアルゴリズムには興味がある。そのコンテンツフィルタをそろそろ自分の会社のProxyへ採用しようとテストを始めようと思う。
実際に、某社で仕事中にいかがわしいサイトを見て喜んでいる社員とか、アダルトサイトを観覧して不当な金銭の請求が有った実例は無い(俺の知ってる限りではね、本当かなぁ〜)。しかし、そのようなサイトへ社内からアクセスしてるかどうか、logを観覧して調査するのも、俺の情報システム部門の役目だと思う。このような背景から、Proxyサーバのモジュールである squid からキック出来るコンテンツフィルタモジュールは無いかと探していたら、この、 squirm と出会った。この squirm は、squid.confからダイレクト起動して、設定ファイルへ正規表現で記述することによるパターンマッチングでURLを拒否して指定のURLへリダイレクトする方式を取っている。
したがって、非常に解りやすい構造である。 squirm には、以下の特徴がある:

■ 実に速い。
■ 実際にはメモリ使用量が殆どない。
■ シグナルを送ることによって squirm が走っている間、コンフィグファイルを再読み込みすることができる。
■ 新しいコンフィグをチェックするための対話的なテスト・モードをサポート。
■ 完全な正規表現パターンマッチングと交換。
■ パターンのためのコンフィグファイルとリダイレクトさせたいネットワークアドレス指定とIPアドレス指定のコンフィグファイル。
■ もし、 squirm のコンフィグファイルが壊れて、 squirm がDodo Modeへ移行しても、squidは動き続ける事が出来る。

こんなことが、 squirmのオフィシャルサイト に書いて有った。(但し、ここのサイトは、2008年12月現在サーバが落ちている)
実際に、テストしてみたが、いい具合に拒否してリダイレクト先へ飛んで行ってくれる(笑)。
実は、もう一つ試した。squidGuardと言うモジュールで、同じようにsquidからキックして使うコンテンツフィルタだが、どういう訳かBerkeleyDBとの連携が上手くいかなかった。BerkeleyDBのバージョンにシビアに依存してるような感じもあった。
ここの書面で、Proxyサーバサービスである、 squid は既にインストールされているものとして割愛する。

テスト&インストール環境)
マシン:Celeron 700MHz ベアボーンPC
OS:Debian GNU/Linux 4.0 etch
squidバージョン:Version 2.6.STABLE5
squirmバージョン:squirm-1.0betaB(2007年6月現在)


1. SquidSquirm (コンテンツフィルタ)との関係
1)コンテンツフィルタはどう動くのか?
1項で説明したように、SquidはLAN側のクライアントとインターネット側のWebアクセスの中継地点でサービスが動いてるのでHTTPのフォワーダー的な要素が有る。したがって、コンテンツフィルタとしては非常に都合が良いサービスといえる。図1はsquidとsquirm(コンテンツフィルタモジュール)との関係を表す図である。squirmはsquidから起動される、squidが起動するとsquirmがキックされてsquidと一緒にシステムに常駐する。squidでキャッシュするHTTPデータをsquirmが同時に監視してURLのパターンマッチで検出して警告メッセージのHTMLを出力して警告する。


  図1


2.ソースのゲットとインストール

http://www.kozupon.com/download/squirm/squirm-1.0betaB.tar.gz

1)ソースをゲットする
オフィシャルサイトからwgetを使ってダウンロードする。 2007年6月現在、squirn-1.0detaB.tar.gzが最新であった。
michi:/# cd /usr/local/src/
michi:/usr/local/src# wget http://squirm.foote.com.au/squirm-1.0betaB.tar.gz
--15:50:01-- http://squirm.foote.com.au/squirm-1.0betaB.tar.gz
=> `squirm-1.0betaB.tar.gz'
Resolving squirm.foote.com.au... 203.32.153.21
Connecting to squirm.foote.com.au|203.32.153.21|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 318,142 (311K) [application/x-tar]

100%[================================>] 318,142 155.44K/s

15:50:04 (155.05 KB/s) - `squirm-1.0betaB.tar.gz' saved [318142/318142]

michi:/usr/local/src# tar zxvf squirm-1.0betaB.tar.gz
squirm-1.0betaB/
squirm-1.0betaB/Makefile
squirm-1.0betaB/log.c
squirm-1.0betaB/paths.h
squirm-1.0betaB/squirm.h
squirm-1.0betaB/squirm.c
squirm-1.0betaB/config.c
squirm-1.0betaB/Makefile.real
squirm-1.0betaB/lists.c
squirm-1.0betaB/lists.h
squirm-1.0betaB/Makefile.profiling
squirm-1.0betaB/regex-0.12/
squirm-1.0betaB/regex-0.12/AUTHORS
squirm-1.0betaB/regex-0.12/ChangeLog
squirm-1.0betaB/regex-0.12/COPYING
squirm-1.0betaB/regex-0.12/INSTALL
squirm-1.0betaB/regex-0.12/NEWS
squirm-1.0betaB/regex-0.12/README
squirm-1.0betaB/regex-0.12/Makefile.in
squirm-1.0betaB/regex-0.12/configure.in
squirm-1.0betaB/regex-0.12/configure
squirm-1.0betaB/regex-0.12/regex.c
squirm-1.0betaB/regex-0.12/regex.h
squirm-1.0betaB/regex-0.12/doc/
squirm-1.0betaB/regex-0.12/doc/Makefile.in
squirm-1.0betaB/regex-0.12/doc/regex.texi
squirm-1.0betaB/regex-0.12/doc/xregex.texi
squirm-1.0betaB/regex-0.12/doc/texinfo.tex
squirm-1.0betaB/regex-0.12/doc/include.awk
squirm-1.0betaB/regex-0.12/doc/regex.info
squirm-1.0betaB/regex-0.12/doc/regex.aux
squirm-1.0betaB/regex-0.12/doc/regex.cps
squirm-1.0betaB/regex-0.12/doc/Makefile
squirm-1.0betaB/regex-0.12/test/
squirm-1.0betaB/regex-0.12/test/ChangeLog
squirm-1.0betaB/regex-0.12/test/TAGS
squirm-1.0betaB/regex-0.12/test/Makefile.in
squirm-1.0betaB/regex-0.12/test/alloca.c
squirm-1.0betaB/regex-0.12/test/bsd-interf.c
squirm-1.0betaB/regex-0.12/test/debugmalloc.c
squirm-1.0betaB/regex-0.12/test/emacsmalloc.c
squirm-1.0betaB/regex-0.12/test/fileregex.c
squirm-1.0betaB/regex-0.12/test/g++malloc.c
squirm-1.0betaB/regex-0.12/test/iregex.c
squirm-1.0betaB/regex-0.12/test/main.c
squirm-1.0betaB/regex-0.12/test/malloc-test.c
squirm-1.0betaB/regex-0.12/test/other.c
squirm-1.0betaB/regex-0.12/test/printchar.c
squirm-1.0betaB/regex-0.12/test/psx-basic.c
squirm-1.0betaB/regex-0.12/test/psx-extend.c
squirm-1.0betaB/regex-0.12/test/psx-generic.c
squirm-1.0betaB/regex-0.12/test/psx-group.c
squirm-1.0betaB/regex-0.12/test/psx-interf.c
squirm-1.0betaB/regex-0.12/test/psx-interv.c
squirm-1.0betaB/regex-0.12/test/test.c
squirm-1.0betaB/regex-0.12/test/tregress.c
squirm-1.0betaB/regex-0.12/test/upcase.c
squirm-1.0betaB/regex-0.12/test/xmalloc.c
squirm-1.0betaB/regex-0.12/test/getpagesize.h
squirm-1.0betaB/regex-0.12/test/test.h
squirm-1.0betaB/regex-0.12/test/regexcpp.sed
squirm-1.0betaB/regex-0.12/test/syntax.skel
squirm-1.0betaB/regex-0.12/test/Makefile
squirm-1.0betaB/regex-0.12/config.status
squirm-1.0betaB/regex-0.12/Makefile
squirm-1.0betaB/log.h
squirm-1.0betaB/main.c
squirm-1.0betaB/regex
squirm-1.0betaB/Copyright
squirm-1.0betaB/GPL
squirm-1.0betaB/README
squirm-1.0betaB/INSTALL
squirm-1.0betaB/squirm.patterns.dist
squirm-1.0betaB/squirm.local.dist

michi:/usr/local/src# cd squirm-1.0betaB

2)コンパイル
初めに、regex.oを作るため、regexディレクトリでコンパイル作業を行う。
michi:/usr/local/src/squirm-1.0betaB# cd regex

michi:/usr/local/src/squirm-1.0betaB/regex# ./configure
checking for gcc
checking for install
checking for AIX
checking how to run the C preprocessor
checking for DYNIX/ptx libseq
checking for POSIXized ISC
checking for minix/config.h
checking for ANSI C header files
checking for string.h
checking for working alloca.h
checking for alloca
checking for working const
checking for gcc to derive installation directory prefix
creating config.status
creating Makefile
creating doc/Makefile
creating test/Makefile

michi:/usr/local/src/squirm-1.0betaB/regex# make clean
rm -f *.o
for d in test; do (cd $d; make CPPFLAGS='' CFLAGS='-O3' CC='gcc' DEFS='-DSTDC_HEADERS=1 -DHAVE_STRING_H=1 -DHAVE_ALLOCA_H=1' LDFLAGS='' LOADLIBES='' clean); done
make[1]: Entering directory `/usr/local/src/squirm-1.0betaB/regex-0.12/test'
rm -f *.o regex cppregex iregex fileregex regexcpp.c syntax
make[1]: Leaving directory `/usr/local/src/squirm-1.0betaB/regex-0.12/test'

michi:/usr/local/src/squirm-1.0betaB/regex# make
gcc -O3 -DSTDC_HEADERS=1 -DHAVE_STRING_H=1 -DHAVE_ALLOCA_H=1 -I. -I. -c regex.c
regex.c: In function 're_match_2':
regex.c:3834: warning: passing argument 1 of 'bcmp_translate' discards qualifiers from pointer target type
regex.c:3834: warning: passing argument 2 of 'bcmp_translate' discards qualifiers from pointer target type
for d in test; do (cd $d; make CPPFLAGS='' CFLAGS='-O3' CC='gcc' DEFS='-DSTDC_HEADERS=1 -DHAVE_STRING_H=1 -DHAVE_ALLOCA_H=1' LDFLAGS='' LOADLIBES='' default); done
make[1]: Entering directory `/usr/local/src/squirm-1.0betaB/regex-0.12/test'
make[1]: Nothing to be done for `default'.
make[1]: Leaving directory `/usr/local/src/squirm-1.0betaB/regex-0.12/test'

生成された、regex.oとregex.hをsquirmを解凍したトップディレクトリへコピーする。
michi:/usr/local/src/squirm-1.0betaB/regex# cp -p regex.o regex.h ..

いよいよ、メインソースをコンパイルする。
michi:/usr/local/src/squirm-1.0betaB/regex# cd ..

makeを行う前に、squirmはsquidオーナーとグループで動こうとする。したがって、Makefileの中のsquidオーナーとグループがデフォルトでsquidになっているため、自分の鯖のsquidオーナーとグループに書き換える。例えば、このホストのsquidはDebianバイナリなので、squidはオーナーがproxyでグループもproxyで有るため、Makefileのsquidの部分をproxyへ変更する。
michi:/usr/local/src/squirm-1.0betaB/regex# vi Makefile
省略
install: all
install -m 755 -o root -g root -d /usr/local/squirm \
/usr/local/squirm/bin
install -m 770 -o root -g proxy -d /usr/local/squirm/etc
install -m 750 -o proxy -g proxy -d /usr/local/squirm/logs
install -m 660 -o root -g proxy squirm.local.dist squirm.patterns.dist \
省略

michi:/usr/local/src/squirm-1.0betaB# make
gcc -c squirm.c -O3 -Wall -funroll-loops
In file included from squirm.c:38:
log.h:35: warning: conflicting types for built-in function 'log'
gcc -c main.c -O3 -Wall -funroll-loops
In file included from main.c:39:
log.h:35: warning: conflicting types for built-in function 'log'
gcc -c config.c -O3 -Wall -funroll-loops
In file included from config.c:29:
log.h:35: warning: conflicting types for built-in function 'log'
gcc -c log.c -O3 -Wall -funroll-loops
In file included from log.c:30:
log.h:35: warning: conflicting types for built-in function 'log'
gcc -c lists.c -O3 -Wall -funroll-loops
In file included from lists.c:30:
log.h:35: warning: conflicting types for built-in function 'log'
gcc -o squirm squirm.o main.o config.o log.o lists.o regex.o

3)リンク
michi:/usr/local/src/squirm-1.0betaB# make install

install -m 755 -o root -g root -d /usr/local/squirm \
/usr/local/squirm/bin
install -m 770 -o root -g proxy -d /usr/local/squirm/etc
install -m 750 -o proxy -g proxy -d /usr/local/squirm/logs
install -m 660 -o root -g proxy squirm.local.dist squirm.patterns.dist \
/usr/local/squirm/etc
install -m 755 -o root -g root --strip squirm /usr/local/squirm/bin

michi:/usr/local/src/squirm-1.0betaB# cd /usr/local/squirm/bin/

michi:/usr/local/squirm/bin# ls -al
total 56
drwxr-sr-x 2 root root 4096 Jun 25 14:32 .
drwxr-sr-x 5 root root 4096 Jun 25 14:32 ..
-rwxr-xr-x 1 root root 46444 Jun 25 14:32 squirm


3.動作テスト
動作テストを行ってみる。以下のようなメッセージが出てホールド状態になればOK!。
CTRL+Cで抜ける。しかし、未だ/usr/local/squirm/etcの中に設定ファイルが入ってないのでエラーメッセージが出ているが・・・・・。
michi:/usr/local/squirm/bin# ./squirm
Squirm running as UID 0: writing logs to stderr
Mon Jun 25 14:33:47 2007:unable to open local addresses file [/usr/local/squirm/etc/squirm.local]
Mon Jun 25 14:33:47 2007:unable to open redirect patterns file
Mon Jun 25 14:33:47 2007:Invalid condition - continuing in DODO mode
Mon Jun 25 14:33:47 2007:Squirm (PID 24917) started


4.コンフィグ

1)squid.confの設定
/etc/squid/squid.confの最後に以下を追加する。
michi:/usr/local/src/squirm-1.0betaB# vi /etc/squid/squid.conf
省略
redirect_program /usr/local/squirm/bin/squirm
       ←squidが動いたときにsquirmを動かす記述
redirect_children 10                         ←立ち上がったときに動かす子プロセスの数

2)squirm.localの設定
実際に対象となるネットワークアドレスもしくは、IPアドレスを記載。
michi:/usr/local/squirm/etc# vi squirm.local
127.0.0
192.168.0
           ←これはネットワークアドレス指定だが、個別のIPアドレスを指定することも出来る。

3)squirm.patternsの設定
最も簡単なパターン。
michi:/usr/local/squirm/etc# vi squirm.patterns
# reject URLs
regexi ^http://.*hoge-i\.com/.* http://xxxxxxxx.com/blocked.html
regexi ^http://.*hogehoge-p\.com/.* http://xxxxxxxx.com/blocked.html
regexi ^http://.*hoge-k\.com/.* http://xxxxxxxx.com/blocked.html

regexi ^http://.*123\.123\.123\.123/.* http://xxxxxxxx.com/blocked.html

記述詳細:
regexi [拒否URLを正規表現で記載] スペース [拒否時のリダイレクト先]

記述の説明:
■ ドメインやホスト名で指定する場合
regexi ^http://.*hoge-i\.com/.* http://xxxxxxxx.com/blocked.html
意味は、 http://xxx.hoge-i.com (xxxはどのようなホスト名でも拒否)もしくは、 http://hoge-i.com のURLを観覧を拒否して http://xxxxxxxx.com/blocked.html へリダイレクトする。

■ IPアドレスで指定する場合
regexi ^http://123\.123\.123\.123/.* http://xxxxxxxx.com/blocked.html
123.123.123.123のIPアドレスのURLは、http://xxxxxxxx.com/bloced.htmlへリダイレクトする。


5.実際に動かしてlogを見る

1)起動する
michi:/usr/local/squirm/etc# /etc/init.d/squid restart

2)サービスの起動状態を見る
michi:/usr/local/squirm/etc# ps -ef

省略
proxy 25552 25546 0 Jun25 ? 00:00:01 (squid) -D -sYC
proxy 25563 25552 0 Jun25 ? 00:00:00 (unlinkd)
proxy 26562 25552 0 06:25 ? 00:00:00 (squirm)
proxy 26563 25552 0 06:25 ? 00:00:00 (squirm)
proxy 26564 25552 0 06:25 ? 00:00:00 (squirm)
proxy 26565 25552 0 06:25 ? 00:00:00 (squirm)
proxy 26566 25552 0 06:25 ? 00:00:00 (squirm)
proxy 26567 25552 0 06:25 ? 00:00:00 (squirm)
proxy 26568 25552 0 06:25 ? 00:00:00 (squirm)
proxy 26569 25552 0 06:25 ? 00:00:00 (squirm)
proxy 26570 25552 0 06:25 ? 00:00:00 (squirm)
proxy 26571 25552 0 06:25 ? 00:00:00 (squirm)
省略

3)squirmのlogの場所と内容
logは、/usr/local/squirm/etcの下に、
squirm.error
squirm.match
squirm.info

の三つのlogがsquirmの初めの起動時に生成される。
ここでは、squirm.match logを見てみる。
このlogは、パターンマッチで引っかかった結果を出力している。

michi:/usr/local/squirm/logs# more squirm.match
Mon Jun 25 14:44:23 2007:http://www.hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 14:49:51 2007:http://www.hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 14:50:23 2007:http://www.hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 14:55:00 2007:http://hoge-i.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 14:55:06 2007:http://www.hoge-i.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:05:36 2007:http://hoge-i.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:10:15 2007:http://www.hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:10:34 2007:http://hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:10:34 2007:http://hogehoge.com/favicon.ico:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:17:10 2007:http://www.hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:17:51 2007:http://sub2.hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:17:51 2007:http://sub2.hogehoge.com/favicon.ico:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:20:22 2007:http://sub2.hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:20:29 2007:http://hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:20:39 2007:http://www.hogehoge.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:31:29 2007:http://hoge-i.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:31:30 2007:http://hoge-i.com/favicon.ico:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:31:33 2007:http://hoge-k.com/:http://xxxxxxxx.com/blocked.html
Mon Jun 25 15:31:33 2007:http://hoge-k.com/favicon.ico:http://xxxxxxxx.com/blocked.html


6.logのローティション

logが肥大化しそうなので、logのローテーションを行う。
michi:/usr/local/squirm/logs# apt-get update

michi:/usr/local/squirm/logs# apt-get install psmisc

michi:/usr/local/squirm/logs# cd /etc/logrotate.d

michi:/etc/logrotate.d# vi squirm
/usr/local/squirm/etc/squirm.error /usr/local/squirm/etc/squirm.match /usr/l
ocal/squirm/etc/squirm.info {
weekly
rotate 4
compress
missingok
postrotate
killall -HUP squirm > /dev/null
endscript
}

以上


 
 
 



Copyright 2007 Kozupon.com.