下位プロキシサーバとしてのSquidの設定

※実際には12/20のネタです。

■squidの入っていない仮想マシン(squeeze)を見つけたので入れてみた。

 Win/Linux/BSD/Solarisがクライアントだろうが、サーバだろうが、
 とりあえずsquidでプロキシアクセスにしてしまう癖があるので、
 なかなかsquidが入っていない環境が見つからなかったので、ネタに出来なかったw。

 ・下位プロキシとしてのsquidの設定なので、
  localnet等のネットワークのアクセス許可については触れない。
 ・また、他のサーバから参照されるわけではないので、もっと厳しい制限をしてもよい。
 ・squid自体はサーバだが、proxyをブラウザと変わらないwebアクセスの
  クライアントとして使っている。

■インストール

$ sudo apt-get install squid

■どこにあるか

$ whereis -b squid
squid: /usr/sbin/squid /etc/squid /usr/lib/squid /usr/lib64/squid /usr/share/squid

■デーモンは実行しているか

$ ps -ef | grep squid | grep -v grep
root      1600     1  0 22:26 ?        00:00:00 /usr/sbin/squid -D -YC
proxy     1603  1600  0 22:26 ?        00:00:00 (squid) -D -YC

■リッスンポートを確認

$ netstat -an | grep 3128
tcp        0      0 0.0.0.0:3128            0.0.0.0:*               LISTEN

■バージョンチェックとコンパイルオプション

$ /usr/sbin/squid -v | sed s/\'/"\n"/g | grep -v "^ \$"
Squid Cache: Version 2.7.STABLE9
configure options:
--prefix=/usr
--exec_prefix=/usr
--bindir=/usr/sbin
--sbindir=/usr/sbin
--libexecdir=/usr/lib/squid
--sysconfdir=/etc/squid
--localstatedir=/var/spool/squid
--datadir=/usr/share/squid
--enable-async-io
--with-pthreads
--enable-storeio=ufs,aufs,coss,diskd,null
--enable-linux-netfilter
--enable-arp-acl
--enable-epoll
--enable-removal-policies=lru,heap
--enable-snmp
--enable-delay-pools
--enable-htcp
--enable-cache-digests
--enable-underscores
--enable-referer-log
--enable-useragent-log
--enable-auth=basic,digest,ntlm,negotiate
--enable-negotiate-auth-helpers=squid_kerb_auth
--enable-carp
--enable-follow-x-forwarded-for
--with-large-files
--with-maxfd=65536
amd64-debian-linux
build_alias=amd64-debian-linux
host_alias=amd64-debian-linux
target_alias=amd64-debian-linux
CFLAGS=-Wall -g -O2
LDFLAGS=
CPPFLAGS=

■telnetで接続(ヘッダのみ抜き出し)
 HTTPリクエストは、「GET http://google.co.jp/ HTTP/1.0」と「Enter」のみ。

$ telnet localhost 3128 | tee telnet_squid.log
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET http://google.co.jp/ HTTP/1.0

HTTP/1.0 301 Moved Permanently
Location: http://www.google.co.jp/
Content-Type: text/html; charset=UTF-8
Date: Mon, 19 Dec 2011 13:34:28 GMT
Expires: Wed, 18 Jan 2012 13:34:28 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 221
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
X-Cache: MISS from vmsqueeze.labunix.net
X-Cache-Lookup: MISS from vmsqueeze.labunix.net:3128
Via: 1.0 vmsqueeze.labunix.net:3128 (squid/2.7.STABLE9)
Connection: close

■ログ「access.log」の確認

$ sudo ls -l /var/log/squid/access.log
-rw-r----- 1 proxy proxy 226 2011-12-19 22:33 /var/log/squid/access.log

$ sudo tail -1 /var/log/squid/access.log
1324301608.961     43 127.0.0.1 TCP_MISS/301 716 GET http://google.co.jp/ - DIRECT/173.194.38.114 text/html

■まずはログ「access.log」の書式を変更

 「TAG: logformat」の変更
 ※以下のコメントアウトを外す

#logformat combined %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh


 「TAG: access_log」を変更
 ※<logformat name>を「squid」から「combined」に変更

★変更前
access_log /var/log/squid/access.log squid

★変更後
access_log /var/log/squid/access.log combined

■initスクリプトのオプション確認

$ sudo grep -i usage /etc/init.d/squid
        echo "Usage: /etc/init.d/$NAME {start|stop|reload|force-reload|restart|status}"

■ステータス確認

$ sudo /etc/init.d/squid status
squid is running.

■実はコンフィグのチェックが事前に行なえる
 ※エラーがなければOK。

$ env LAN=C man squid | grep check
       -k reconfigure | rotate | shutdown | interrupt | kill | debug | check |
$ sudo /usr/sbin/squid -k check && echo $?
0

■ユーザ権限で実行すると、「0」以外が返る

$ /usr/sbin/squid -k check >/dev/null 2>&1;echo $?
アボートしました
134

■squidの設定をリロードする

$ sudo /etc/init.d/squid reload
Reloading Squid configuration files.
done.

■再チェック(「Enter」を忘れずに。)

$ telnet localhost 3128 | tee telnet_squid.log
GET http://google.co.jp/ HTTP/1.0


■combined 形式のログ

$ sudo tail -1 /var/log/squid/access.log
127.0.0.1 - - [19/Dec/2011:22:50:12 +0900] "GET http://google.co.jp/HTTP/1.0GEThttp://google.co.jp/
 HTTP/1.0" 301 783 "-" "-" TCP_MISS:DIRECT

■common 形式のログ

$ sudo tail -1 /var/log/squid/access.log
127.0.0.1 - - [19/Dec/2011:22:52:03 +0900] "GET http://google.co.jp/ HTTP/1.0" 301 725 TCP_MEM_HIT:NONE

■ポートの変更
 ※8080はoracle-xeが使っているので、7080とした。

 「TAG: http_port」を変更する

★変更前
http_port 3128
★変更後
http_port 7080

■チェックがOKならリロード

$ sudo /usr/sbin/squid -k check && sudo /etc/init.d/squid reload
Reloading Squid configuration files.
done.

$ netstat -an | grep 7080
tcp        0      0 0.0.0.0:7080            0.0.0.0:*               LISTEN

■上位サーバのプロキシを参照する
 クライアントブラウザはw3mに変更

 書式: cache_peer [親プロキシホスト名] [親プロキシポート] 3130 default

$ sudo grep ^cache_peer /etc/squid/squid.conf
cache_peer debian-lenny parent 3128 3130 default

$ sudo /usr/sbin/squid -k check && sudo /etc/init.d/squid reload
Reloading Squid configuration files.
done.

$ export http_proxy=http://127.0.0.1:7080/;w3m http://google.co.jp

※時刻にズレがあるが、ホストOSとゲストOSの時刻同期の問題。
 実際は「tail -f」で待ち構えていても、下位⇒上位のアクセスのズレは一瞬。

★現在設定中のプロキシサーバのログ
$ sudo tail -1 /var/log/squid/access.log
127.0.0.1 - - [19/Dec/2011:23:49:03 +0900] "GET http://www.google.co.jp/ HTTP/1.0" 200 10856 "-"
 "w3m/0.5.2+cvs-1.1027" TCP_MISS:FIRST_PARENT_MISS

★上位プロキシサーバのログ
$ sudo tail -1 /var/log/squid/access.log
192.168.72.108 - - [19/Dec/2011:23:51:20 +0900] "GET http://www.google.co.jp/ HTTP/1.0" 200 10708
 "-" "w3m/0.5.2+cvs-1.1027" TCP_MISS:DIRECT

■一応ローカルIPを隠蔽するはずの、「forwarded_for off」を設定しておく
 「X-Forwarded-For: 192.1.2.3」が、
 「X-Forwarded-For: unknown」になるはずだが、
 telnetではそもそも、そんなヘッダは出ていない。

 また、「TAG: via」の修正で、「via off」としたが、しっかりヘッダに出てる。
 「X-Cache」の制御については特に設定は見つからなかった。

$ telnet localhost 7080 | tee -a test.log
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET http://www.yahoo.co.jp/ HTTP/1.0

HTTP/1.0 200 OK
Date: Mon, 19 Dec 2011 15:03:30 GMT
P3P: policyref="http://privacy.yahoo.co.jp/w3c/p3p.xml",
 CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY
 ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"
Expires: -1
Pragma: no-cache
Cache-Control: private, no-cache, no-store, must-revalidate
X-XRDS-Location: http://open.login.yahoo.co.jp/openid20/www.yahoo.co.jp/xrds
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
X-Cache: MISS from debian-lenny
X-Cache-Lookup: MISS from debian-lenny:3128
X-Cache: MISS from vmsqueeze.labunix.net
X-Cache-Lookup: MISS from vmsqueeze.labunix.net:7080
Via: 1.1 debian-lenny:3128 (squid/2.7.STABLE3), 1.0 vmsqueeze.labunix.net:7080 (squid/2.7.STABLE9)
Connection: close

■まとめ

隠蔽が目的ではなく、クライアントとして「access.log」で
「どこにアクセスしたかが残る」というところが大事。

透過型にしなくても、ブラウザの設定は自身で制御出来るので、
各ブラウザにプロキシ設定をして、
全ブラウザから見た出口としてアクセスログを集約する
(sshのポート転送を使って無理やり透過型にしたり、
 定番のiptablesのNATで透過型設定にしたりも出来るが。。。)

ログを見ればどのブラウザを使ったかも分かるので、
Webサーフィンで何かおかしいと思ったら、まずはsquidのログを見れば良い。