Proxyキャッシュサーバ設定術―Squidの設定

(これはSoftware Design 2001年12月号の特集 「知っておきたいProxyサーバ活用ガイド」の第2章の原稿です)

SquidはHTTP,FTPをはじめとする 各種のプロトコルに対応した キャッシュ機能付きのproxyサーバです.

多くのUNIX系OSで動作し, 高機能・高性能なproxyサーバの一つと言われています. それ自体オープンソースソフトウェアであることもあって 場所を問わず広く利用されています. Squidに関する最新の情報はホームページ <URL:http://www.squid-cache.org/> で参照できます. また,多くの人々が利用していることもあって ホームページ以外にも多くの情報サイトがあります. 日本語で書かれた情報も比較的たくさんありますので, 検索サイトを使って探してみると良いでしょう.

ここではSquidのインストールから基本的な設定, 関連ツールや運用方法などについて解説します.

インストール

なにはともあれインストールしないことには話が始まりません. インストール方法には大きくわけて二通りあります. 一つは公開されているSquidのソースを取ってきて 自分で環境を構築する方法. もう一つは各種OSによって提供されている バイナリパッケージを使う方法です.

バイナリパッケージを使う

Linux系ディストリビューションやFreeBSD,NetBSDなどでは 各開発グループによってメンテナンスされている バイナリパッケージが提供されています.

一般にバイナリパッケージには Squidの動作に最低限必要となるもの, つまりSquid本体,設定ファイルの雛型, データを置くためのディレクトリ,… などが収められています. それらは各OS用に調整されたより良い状態で提供されているわけですが, これは言ってみれば, 後述するソースからの構築で必要とされる 手順までをすべて含めてパックしてあるということになります. したがって特にそうしたい理由がないのであれば, それらバイナリパッケージを使うのがお手軽で確実だと言えるでしょう.

ソースから構築する

とは言ってもソースから構築したいこともあるでしょう. パッケージで提供されるSquidの構築のされ方では機能的に過不足があるとか, パッケージが最新のバージョンに追述しきれていないなど いくつかの理由が考えられます.

SquidのソースはSquid FTP Mirror Sites <URL:http://www.squid-cache.org/Mirrors/ftp-mirrors.html> にリストされているサイトから入手できます. 執筆時点での最新の安定版は2.4.STABLE2というバージョンで, squid-2.4.STABLE2-src.tar.gzという ファイル名で提供されていますので適当なミラーサイトから入手してください.

入手できたら適当なディレクトリで展開します. するとsquid-2.4.STABLE2というディレクトリができて, その中にソース一式が展開されます.

$ tar xvfz squid-2.4.STABLE2-src.tar.gz
$ ls squid-2.4.STABLE2
CONTRIBUTORS  QUICKSTART     config.cache    doc/      makefile.in
COPYING       README         config.log      errors/   scripts/
COPYRIGHT     TODO           config.status*  icons/    snmplib/
CREDITS       acconfig.h     configure*      include/  src/
ChangeLog     auth_modules/  configure.in    lib/      test-suite/
INSTALL       cfgaux/        contrib/        makefile

Squidは他の多くのソフトウェアと同じく configureスクリプトによって構築方法の調整が可能となっています. squid-2.4.STABLE2に移動して, 次のようにconfigureスクリプトを--help付きで実行すると どのような点について調整できるかとそのデフォルト値かがわかります.

$ cd squid-2.4.STABLE2
$ ./configure --help

どのようなオプションが必要かがわかったら, それを指定してconfigureスクリプトを実行. その上でmake,それからrootになって make installと実行するとSquidのインストールは完了です.

$ ./configure
$ make
$ su
# make install

なおmake installの前にmake -n installとすると 事前にどこにどのようなファイルがインストールされるのかを 確認することができます.

設定

インストールが終ったらSquidのための設定を行いましょう. Squidについてくる設定ファイルでは基本的に どこからのアクセスも受け付けない設定となっていますからこの作業は必須です. パッケージを使った場合でもおそらくこれと同じ状態であるでしょう. もしそうでなかったとしてもアクセス制限に関する調整は必須になります.

Squidの設定ファイルはsquid.confです. ソースからインストールした場合には configure時に--prefixで指定したディレクトリの下の etcディレクトリに置かれます. デフォルトでは/usr/local/squid/etc/squid.confですが, パッケージからインストールした場合には これとは異っているかもしれません. Linux系OSなどいくつかの環境では/etc/squid.confに置かれています.

Squidの動作はすべてsquid.confで調整することができます. 逆に言うとSquidに関するすべてをこのファイル書く必要があるわけで, それだけにsquid.confのサイズはかなりのものとなっています. 一見すると目をまわしそうになるかもしれませんが, 運用開始時に必ず必要となる設定はそれほど多いわけではありません. ここではそれを以下のように分類して解説します.

もちろんここで挙げた以外にも多くの設定項目がありますが, それらは運用しながらチューニングしていくとよいでしょう.

アクセスコントロール

Squidのデフォルトの設定ファイルで ほとんどすべてのアクセスを受け付けないようになっているのには理由があります. 安易にproxyサーバの運用を開始すると 踏台として使われてしまう可能性があるからです. つまり自分の身元を明したくない何者かが 設定や管理のあまいproxyサーバを経由して どこか別のサイトになんらかの攻撃をしかけるということが起こり得るわけです.

また,たとえばファイアウォール上で動作させていて, 組織内のプライベートなネットワークとそれ以外のネットワークの 橋渡しをしているようなケースがあったとします. そうした環境においては以下のように運用すべきでしょう.

正しく設定するためには「正しい状態」をきちんと定義しておき, それを設定に反映させなくてはなりません. もしもそのどちらかに穴があると, 本来アクセスできてはならない 外部からプライベートネッワーク上のホストへのアクセスが 可能となってしまったりしかねません. 実際の設定をはじめる前にどこからのどういうアクセスを受け付けて, どういったアクセスを拒絶するのかというポリシーを きちんと決めておきましょう.

aclhttp_access

Squidへのアクセスの制御は aclhttp_accessで行います. まずaclですが,これは「条件」を定義するためのものです. たとえば「*.example.netに対するアクセス」とか 「192.168.1.*からのアクセス」, 「パス部分にeroを含むURLへのアクセス」などといった 「条件」に名前を付けて定義します. ちなみにそれぞれ以下のような設定になります.

一般的な書式は以下の通りです.

acl <名前> <タイプ> <引数> <引数> <引数> ...

上の例で<タイプ>にあたるのはdstdomainsrcurlpath_regexです.<タイプ>の後に続いているのが引数となり, 指定されたタイプにおいてどのような条件とするかを決定します. ここでは三種類のタイプを例示しましたが これ以外にもいくつかのタイプがあります. どのようなタイプがあるかはsquid.confに コメント*1として書かれいますので そちらを参照してください.

aclで定義した「条件」を使って 実際のアクセス制御を設定するのがhttp_accessの役割りです. 書式は以下の通りです.

http_access <allow|deny> <名前> <名前> <名前> ...

<allow|deny>の部分にはallowまたはdenyのどちらかを記述し, 続く<名前>で示される「条件」にマッチするアクセスを許可するか それとも拒絶するかを指定します. <名前>が二つ以上指定された場合には すべての「条件」にマッチしたものについて 許可または拒絶するという意味になります. これに対してaclで複数の<引数>を指定した場合には 「そのうちのどれか」という意味になりますので注意が必要です.

# これはポート番号が443か563のどちらかという意味だが
acl SSL_ports port 443 563

# こちらはmanagerとlocalhostの両方にマッチした場合にallowという意味になる
http_access allow manager localhost

Squidがクライアントからの要求を受けると squid.confの中で最初に書かれているものから順に 「条件」にマッチするかをチェックされ, どこかでマッチしたらそこで指定された内容に従って処理を続けます. もしもまったくマッチしなかったら 一番最後のhttp_acessで指定されている <allow|deny>と逆の内容に従います.

アクセスコントロールの例

デフォルトで提供されるsquid.confの中から アクセスコントロール関係の設定をぬき出して解説してみましょう.

acl all src 0.0.0.0/0.0.0.0

srcはアクセス元のIPアドレスを指定するタイプなのですが, 0.0.0.0/0.0.0.0はどのようなIPアドレスにもマッチするため 結局的にすべての要求にマッチします.

acl manager proto cache_object

protoではプロトコルを指定することができます. 通常はhttpftpが指定されますが, ここでは特殊なcache_objectというプロトコルを指定しています. これはSquid自身が管理しているデータにアクセスするためのプロトコルで, 後述するcachemgr.cgiというプログラムが使用しています.

acl localhost src 127.0.0.1/255.255.255.255

localhostからのアクセスにマッチします.

acl SSL_ports port 443 563
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443 563     # https, snews
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

各ポートへのアクセスがマッチします. Safe_portsのように複数回記述がある場合, すべての記述の中のどれかという意味になります.

acl CONNECT method CONNECT            # … (A)

methodはHTTPプロトコルの各メソッドに対してマッチします. ここで指定されているCONNECTというメソッドはあまりなじみのないものですが, HTTP中でTLSを開始するための特別なメソッドです. 次からがアクセスコントロールの設定になります.

http_access allow manager localhost
http_access deny manager

意味的にはこれで一セットです. すなわちmanagerにマッチするもののうち localhostにもマッチするアクセスについては許可するけれど, それ以外のアクセスについては拒絶するという設定になります.

http_access deny !Safe_ports

このようにaclの名前の前に「!」をつけると 条件にマッチしないときにallowないしはdenyが適用されます. この例について言うと,アクセス先のポート番号が Safe_portsにリストされている 8021,… ,777のいずれでもない場合に要求が拒絶されます.

http_access deny CONNECT !SSL_ports   # … (B)

これはCONNECTにマッチし, しかもSSL_portsにマッチしない要求を拒絶する設定です.

http_access deny all                  # … (C)

デフォルトの設定ではこれが最後の設定になります. これはSquidに対するすべての要求を拒絶するためのものです. ここまでの設定はmanagerに関するもの以外の すべてが拒絶するための設定でしたから, 結局はほとんどすべてのアクセスが拒絶され, 唯一cachemgr.cgiからだけSquidにアクセスできる というのがデフォルトでの状態であるということになります.

自サイトからのアクセスを許可しよう

proxyサーバとして動作させるためには, 少なくとも自サイトのネットワークからの要求を許可しなくてはなりません. そこでまずこのような設定を加えましょう.

acl localnet src 192.168.1.0/255.255.255.0

これを(A)の次の行あたりにいれておきます (IPアドレスの指定はみなさんのネットワークに合わせてください). そして(C)の前の行あたりに以下の設定を加えます.

http_access allow localnet

これで自サイト(ここでは192.168.1.0/255.255.255.0)からの アクセスが許可されるようになるわけです. ここでのポイントは(C)の前に,そして(B)の後に 設定を追加するということです.

デフォルトで設定されているいくつかのアクセス禁止設定は 不審なアクセスをしめ出すための最低限のものであり,一般に有効です. そして最後の一行(C)によってすべてのアクセスを禁止しているわけですから, (B)(C)の間において必要最低限の アクセス許可設定をするようにしておくことで 設定上の穴をある程度ふせぎやすくなります.

使用リソースの制御

続いてSquidが使用するリソースについての設定です. ディスク容量とメモリ容量についての設定になるわけですが, これらもまたしっかりと設定しておかなくてはなりません.

前者についてはSquidを通った情報をキャッシュしておくために 使われるわけですので,これが少なすぎるとキャッシュが有効に活用されません. そうかといってディスク容量をさけばさくほど キャッシュのヒット率が上がるかというと,一般にはそうでもないようです. 一方,後者はメモリ上にキャッシュを置くための領域を どれくらとるかという設定になります. メモリ上のキャッシュにヒットすれば それだけ速くレスポンスを返すことができますから サイズが大きい方が良いと言えるでしょう. しかし,メモリはディスクよりもサイズ的に小さい上に, 他のプロセスとのかねあいもありますので やたらと大きくすることもできません.

ディスク容量についての設定

ディスク容量の調整はキャッシュ用に使う場所の指定とともに行います.

cache_dir ufs /usr/local/squid/cache 100 16 256

この設定で/usr/local/squid/cache以下が キャッシュ用の領域として使われます. もし必要ならパスを変更しておきましょう. パス名の後に続く100というのが領域のサイズ指定で, これは100Mバイトまでにするということを意味します. ですからたとえば500Mバイトまでにしたいのであれば この部分を500に書き換えればよいわけです.

キャッシュ領域の使い方に関係する設定項目をもう一つ挙げておきます.

maximum_object_size 4096 KB

この設定によって一つ一つのデータのサイズが 4096Kバイトまでのものだけがキャッシュに保存されるようになります. これより大きいものについてはSquidを通ってクライアントには渡りますが, キャッシュには入りません.

メモリ容量についての設定

メモリ容量を制限するのは以下の設定によって行います.

cache_mem 8 MB

ただしこの設定はSquidのプロセスのサイズを制御するものでは ありませんのでその点に注意が必要です. コメントの中にも記述がありますが, プロセス自体のサイズはここで設定した値の2〜3倍になり得るようです.

動作権限

基本的な設定のしめくくりとして Squidが動作する際の権限を確認しておきましょう.

cache_effective_user nobody
cache_effective_group nogroup

Squidはここで設定されているユーザ・グループの権限において動作します. たとえばディスク上のキャッシュに対する読み書きや ログファイルに対する操作などに関係してきます.

通常は専用のユーザとグループを作って, その権限で動作させるようにした方がよいでしょう. たとえばユーザsquid,グループsquidを作って その権限で動作させるのであればこのようにしておきます.

cache_effective_user squid
cache_effective_group squid

動作確認

とりあえずここまでで解説した設定項目の内容を確認して, 必要であれば値を変更しておいてください. 運用に必要となる最低限の設定はカバーできているはずです.

前準備

パッケージを使ってインストールした場合には ここでの作業は必要ないかもしれません. 通常は設定を各環境用に調整するだけで すぐに運用できるようになっているはずです. しかし,ソースからインストールした場合には 実際に動作させるまでにもう少し準備が必要となります.

まず必要となるのがキャッシュ用のディレクトリを作っておくこと. cache_dirに設定されているディレクトリを作り, その持ち主とグループをcache_effective_usercache_effective_groupで設定されているものにします.

# mkdir /usr/local/squid/cache
# chown squid.squid /usr/local/squid/cache

さらにログファイル用のディレクトリについても 持ち主とグループを変更しておきます. ログファイルのファイル名はcache_access_logcache_logcache_store_logの各設定に従って決まりますが, 通常は一つのディレクトリに集められているでしょう. デフォルトの設定においてもそうで, たとえば/usr/local/squid/logs以下に すべてのログファイルが作られるようになっています.

# chown squid.squid /usr/local/squid/logs

以上が完了したらキャッシュ用のディレクトリの初期化をします.

# squid -z
2001/10/11 18:36:41| Creating Swap Directories

これで前準備はおしまいです.

動かしてみよう

いよいよSquidの起動です. Squid本体はsquidという名前でインストールされているはずです. インストール場所によってはPATHが通っていないでしょうから, 必要に応じてフルパスで次のように起動します.

# /usr/local/squid/bin/squid -NCd1

今は動作確認のために動かしてみているので オプションとして-NCd1を指定しています. これらのオプションによってdaemon化せず, かつログ情報を標準エラー出力にも出力するという動作をしてくれます. この場合,Ctrl-CによってSquidを終了させられますから 何か異常があったらすぐにSquidを止めるましょう.

Squidが正しく動作できるよう準備が整っていると 以下のようなログ情報が出力されるはずです.

2001/10/11 18:55:26| Starting Squid Cache version 2.4.STABLE2 for i686-pc-linux-gnu...
2001/10/11 18:55:26| Process ID 5346
2001/10/11 18:55:26| With 1024 file descriptors available
2001/10/11 18:55:26| Performing DNS Tests...
2001/10/11 18:55:26| Successful DNS name lookup tests...
2001/10/11 18:55:26| DNS Socket created on FD 4
2001/10/11 18:55:26| Adding nameserver 192.168.1.1 from /etc/resolv.conf
2001/10/11 18:55:26| Unlinkd pipe opened on FD 9
2001/10/11 18:55:26| Swap maxSize 102400 KB, estimated 7876 objects
2001/10/11 18:55:26| Target number of buckets: 393
2001/10/11 18:55:26| Using 8192 Store buckets
2001/10/11 18:55:26| Max Mem  size: 8192 KB
2001/10/11 18:55:26| Max Swap size: 102400 KB
2001/10/11 18:55:26| Rebuilding storage in /usr/local/squid/cache (DIRTY)
2001/10/11 18:55:26| Using Least Load store dir selection
2001/10/11 18:55:26| Set Current Directory to /usr/local/squid/cache
2001/10/11 18:55:26| Loaded Icons.
2001/10/11 18:55:26| Accepting HTTP connections at 0.0.0.0, port 3128, FD 10.
2001/10/11 18:55:26| Accepting ICP messages at 0.0.0.0, port 3130, FD 11.
2001/10/11 18:55:26| WCCP Disabled.
2001/10/11 18:55:26| Ready to serve requests.
2001/10/11 18:55:26| Done scanning /usr/local/squid/cache swaplog (0 entries)
2001/10/11 18:55:26| Finished rebuilding storage from disk.
2001/10/11 18:55:26|         0 Entries scanned
2001/10/11 18:55:26|         0 Invalid entries.
2001/10/11 18:55:26|         0 With invalid flags.
2001/10/11 18:55:26|         0 Objects loaded.
2001/10/11 18:55:26|         0 Objects expired.
2001/10/11 18:55:26|         0 Objects cancelled.
2001/10/11 18:55:26|         0 Duplicate URLs purged.
2001/10/11 18:55:26|         0 Swapfile clashes avoided.
2001/10/11 18:55:26|   Took 0.5 seconds (   0.0 objects/sec).
2001/10/11 18:55:26| Beginning Validation Procedure
2001/10/11 18:55:26|   Completed Validation Procedure
2001/10/11 18:55:26|   Validated 0 Entries
2001/10/11 18:55:26|   store_swap_size = 84k
2001/10/11 18:55:27| storeLateRelease: released 0 objects

たくさんのログ情報の中にうもれてしまって ややわかりにくいかもしれませんが, Ready to serve requestsというメッセージが出ていればひとまずOKです. キャッシュ用のディレクトリや ログファイルのための準備ができているというということになります.

設定内容の確認

とりあえず動作していることがわかったら, 先程行った設定が正しくできているかどうかを確認をしましょう.

まず,Squidがどういう動作をすべきかを再度見直しておきます. ここで扱っている例は比較的単純で,以下の通りです.

確認作業はこれに従って行われなくてはなりません. 手順はこのようになるでしょう.

  1. Squidが動作しているホストから 自ホスト以外のWebサイトにアクセスできることを確認する.
  2. 192.168.1.0/255.255.255.255にあるホストでブラウザのproxyの設定を行う. その上で1でアクセスできることを確認したWebサイトにアクセスしてみる.
  3. 192.168.1.0/255.255.255.255以外にあるホストでも同様のことを行い, アクセスできないことを確認する.

このときSquidのアクセスログを見ながら確認すると良いでしょう. アクセスログはcache_access_logに指定されたファイルに書き出されますから このようにしておくと便利です.

$ tail -f /usr/local/squid/logs/access.log

実際にテストを行ったときのログはこのようなものでした.

1002868362.228    189 192.168.1.31 TCP_MISS/200 6992 GET http://www.ruby-lang.org/ja/index.html - DIRECT/210.251.121.214 text/html
1002868465.792      2 192.168.1.31 TCP_MEM_HIT/200 6989 GET http://www.ruby-lang.org/ja/index.html - NONE/- text/html
1002868472.772      2 172.16.1.100 TCP_DENIED/403 1039 GET http://www.ruby-lang.org/ja/index.html - NONE/- -

1〜2行目が正しいアクセスで許可されるべきものであり, 3行目は不正なアクセスです. ログの中でまず見るところは4番目のフィールドです. TCP_DENIEDとなっているのが拒絶されたアクセスで, それ以外は許可されたアクセスを表しています. 詳しいログの読み方は後述しますが, この3行のログから次のことを確認できます.

ただしこれだけではテストがあまい可能性もありますから, できるだけ多くのテストケースを作って アクセス制限の設定に穴がないことを確認しておく方が良いでしょう. 特に組織外からアクセスしてみることが可能であれば, それをやっておくべきです.

コラム: ルータでのフィルタリング

Squidの設定によって適切にアクセス制限をかけることは必須であると言えます. しかし特に外部からのアクセスに対してはそれだけで安心してしまうのでなく, ルータでのフィルタリングを併用することをおすすめします.

一般に組織外と接続しているルータでは 本当に必要なトラフィックだけが通れるようにしておかなくてはなりません. ここで扱っているようなproxyに関係する通信は (特別な事情がない限り)組織外とやり取りするものではあり得ません. よってルータにおいてもこのやり取り(Squidのデフォルトで言えば ポート3128と3130を使った通信)はフィルタリングの対象としておくべきであると 考えられます.

Squidの運用を開始するにあたってルータの設定も見直してみるのはどうでしょうか.

起動と停止

一連の動作確認が終ったらCtrl-CでいったんSquidを止め, 実際の運用のために起動し直します. 先程は動作確認のために-NCd1オプションを付けていましたが, 実運用においてはこのオプションは必要ありません. 単に/usr/local/squid/bin/squidを実行するだけで, daemonとして動作してくれます. 動作中のSquidを停止させるのにもsquidを使いますが, その場合には-k shutdownオプションを付けて実行します.

マシンの起動・停止に合わせてSquidも起動・停止させたい場合には お使いのOS環境に合わせて上記のコマンドが実行されるように 設定すると良いでしょう. バイナリパッケージからインストールした場合には なにもしなくてもそのようになっていると思われます. それぞれの環境で確認してみてください.

日々の運用

基本的な設定が終ったらあとは運用を開始して, 実際にproxyサービスを使ってもらう段階に入ります. 運用段階に入るとSquidを安定した状態で できる限り稼働させておくことがまず重要になります. そしてでき得ればキャッシュが有効に活用されるよう 設定を調整していくことも望まれるでしょう.

以下ではSquidの活動状況を知る一番の手がかりとなるアクセスログの見方と 運用を支援してくれるいくつかのツール, そしてキャッシュの調整に関するいくつかの設定について解説します.

ログの読み方

アクセスログの書式がどうなっいるかはSquidのソースの中の doc/Release-Notes-1.1.txtというファイル書かれています. それによるとアクセスログの各行は10の部分から構成されていて, それぞれ次のような意味を持っています.

  1. タイムスタンプ

    やり取りが終了した時刻です.

  2. 経過時間

    やり取りに要した時間をミリ秒で記録します.

  3. 要求元

    クライアントのIPアドレスか, log_fqdnという設定がonになっているときには ホスト名が記録されます.

  4. アクセスタグ/HTTPコード

    クライアントからの要求がどのように扱われたかということと クライアントに返したHTTPのレスポンスコードを/で区切って記録します. 前者の記録にアクセスタグというものが使われます. アクセスタグがどのようなものかは後述します.

  5. サイズ

    クライアントに送られたデータ量がバイト単位で記録されます.

  6. メソッド

    HTTPのメソッドです.

  7. URL

    要求されたURLです.

  8. ident

    クライアント上のユーザ名をidentを使って記録しようとするものですが, ident_lookup_accessが適切に設定されていない限り -が記録されます. また適切に設定されていたとしても, 有用な情報が記録されるとは限りません.

  9. hierarchyタグ/ホスト名

    SquidはSquid同士を連携させてキャッシュを 共有することができるという大きな特長があり, そのため要求を処理するために他のSquidから キャッシュデータをもらうこともあります. ここには要求された情報をどうやって(hierarchyタグ) どこから(ホスト名)入手したのかが記録されます.

  10. Content-Type

    HTTPのContent-Type情報が記録されます.

アクセスタグ

アクセスタグは要求がどのように処理されたかを表すものです. 先程少しだけ触れたSquid同士の連携を行っているケースでは もう少し別のタグが使われることがありますが, そうでない場合には以下のどかれが使われます.

TCP_HIT

求要された情報がキャッシュの中から見付かった.

TCP_MISS

キャッシュの中にはなかったので オリジナルの情報を持つサーバにアクセスした.

TCP_REFRESH_HIT

情報はキャッシュの中にあったが, すでに古くなっていたためオリジナルの情報に If-Modified-Since付きでアクセスした. しかしサーバからは「キャッシュの中にある状態から 更新されていない」という返事があった.

TCP_REFRESH_MISS

上と同様にサーバにアクセスし より新しい情報を得られた.

TCP_REF_FAIL_HIT

上と同様にサーバにアクセスしたが アクセスに失敗したために キャッシュ中の古い情報をクライアントに送った.

TCP_CLIENT_REFRESH

クライアントからPragma: no-cache付きのアクセスが行われたため, キャッシュ中に情報があるかどうかは関係なく オリジナルのサーバにアクセスした.

TCP_IMS_HIT

クライアントからIf-Modified-Since付きのアクセスがあったため, サーバにIf-Modified-Since付きでアクセスを行ったが キャッシュ中の情報が十分新しかったためそれを返した.

TCP_IMS_MISS

上と同様にアクセスした結果,より新しい情報が得られた.

TCP_SWAPFAIL

キャッシュ中にあるはずの情報が実はなかった(エラー).

TCP_DENIED

そのアクセスを拒絶した.

アクセスログの中のこうしたタグを監視することによって, たと不正アクセスの検出やキャッシュの有効性の確認などを行うことができます. 一例ですが以下に示す簡単なRubyスクリプトによって 正常に処理できたアクセスのうちで キャッシュ中の情報が活用された度合を計算することができます.

#!/usr/bin/ruby

start_time = nil
end_time   = nil

hit  = 0
miss = 0
hit_size  = 0
miss_size = 0

while line = ARGF.gets
  info = line.split(/\s+/, 10)

  end_time = info[0].to_i
  start_time ||= end_time

  tag  = info[3].split('/').first
  case tag
  when /TCP_.*HIT/
    hit += 1
    hit_size += info[4].to_i
  when /TCP_.*MISS/
    miss += 1
    miss_size += info[4].to_i
  end
end

printf("start: %s\n", Time.at(start_time))
printf("  end: %s\n", Time.at(end_time))
printf(" rate: %5.2f%%\n", hit/(hit + miss).to_f*100)
printf(" size: %dMB (%5.2f%%)\n", hit_size/1024/1024,
                                  hit_size/(hit_size + miss_size).to_f*100)

以下にこのスクリプトの実行例を示します.

$ ruby rate.rb /var/log/squid/access.log
start: Wed Oct 10 16:31:19 JST 2001
  end: Fri Oct 12 16:21:27 JST 2001
 rate: 44.20%
 size: 263MB (79.99%)

これで一応の集計はできますがご覧の通りごくごく簡単なものです. より本格的な集計をしなくてはならないの場合には もっときちんとしたプログラムを自作するか, あるいは多くの人々によって開発されている 様々な集計ツールの中から用途に合うものを探すのがよいでしょう. そうしたログ解析ツールを紹介しておきます.

支援ツール

運用を支援するツールという意味では 前述のログ解析ツールもそうなのですが, Squid自体にも運用を支援するツールがついています.

client

squidといっしょにインストールされるコマンドです. これはSquid経由でWebサイトにアクセスするコマンドラインクライアントで, URLを指定すると対応する情報を取り寄せることができます.

$ /usr/local/squid/bin/client http://www.ruby-lang.org/ja/index.html

ヘッダも含めたすべての情報が標準出力に出力されます. これだけではあまり役に立ちそうにないのですが, -mオプションでpurgeを指定すると 指定したURLに対応するキャッシュ中のデータを 削除できるという用法があります.

$ /usr/local/squid/bin/client -m purge http://www.ruby-lang.org/ja/index.html

ただし,この時,メソッドPURGEでのアクセスが 許可されている必要があります.つまり以下のような設定が squid.confに入っていなければなりません.

acl localhost src 127.0.0.1/255.255.255.255
acl purge method PURGE
http_access allow purge localhost
http_access deny purge

cachemgr.cgi

Squidといっょに提供されているもう一つのツー分です. cachemgr.cgiという名前からわかる通り CGIプログラムとして作られているもので, これを介してSquidに対する様々な操作をすることができます.

cachemgr.cgiは通常のmake installではインストールされませんので, 使用に際して適切な場所にコピーしておきます. またさらにHTTPサーバ上でCGIプログラムを 動作させるための設定が必要となります.

$ cd squid-2.4.STABLE2/src
# su
# cp cachemgr.cgi /foo/bar/cgi-bin/

使い方は簡単で,cachemgr.cgiに対して 適当なブラウザでアクセスするだけです. ただしcache_objectプロトコルでのアクセスが 許可されていることが必要です. このときSquidに対するアクセスは cachemgr.cgiを起動したHTTPサーバのある ホストからになることに意注してください.

acl manager proto cache_object
http_access allow manager localhost
http_access deny manager

cachemgr.cgiを介して行うことのできる操作の中には 現存のSquidの設定を見たりSquidを停止させたりするものがありますが, これらにはパスワードによるアクセス制限がかけられています. このパスワードに関する設定はsquid.conf中で以下のように行います.

cachemgr_passwd secret config shutdown

この例では設定を見る機能configと Squidを停止する機能shutdownについてのパスワードを secretに設定しており, それと同時にそれぞれの機能が有効になります. パスワードとしてnoneを指定すると パスワードなしでこれらの機能を使うことができるようになりますし, config shutdownのように個々の機能毎に指定するのではなく allという指定をすることですべての機能にパスワードをかけることもできます.

cachemgr_passwd secret all

cachemgr.cgiは使い方によっては便利なものですが, 適切に扱わないと大きな穴になりかねません. 使用にあたってはHTTPサーバ側でのアクセス制限を併用するなど よく注意してください.

キャッシュの調整

この節のしめくくりにキャッシュに関する調整の仕方について 少しだけふれておきましょう.

入れるもの入れないもの

まず何をキャッシュに入れて何を入れないのかという調整です. よくあるのは自ネットワーク上のサイトにある情報については わざわざキャッシュしたくないという設定でしょう. また,特定の条件に当てはまる場合に キャッシュさせたくないということもあるかもしれません.

このような設定を行うにはno_cacheを使います. デフォルトのsquid.confにはこのような設定が含まれています.

acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY

ごらんの通りno_cacheでもaclを使うのです. 実際にはaclは非常に多くの場面で使われています. ここで紹介したno_cacheもそうですが 「ある条件にマッチしたときにこのようにしたい」 というときにはほとんどすべて aclによって条件が表現されるようになっています.

さて,上の例の意味するところですが, これはURLのパス部分にcgi-bin?を含む場合 その情報はキャッシュに入れないようにするということになります. そうしたURLから得られる情報は CGIスクリプトなどから動的に生成されるものが多く, キャッシュしてもあまり意味がないことが多いため このような設定がデフォルトで入っているのでしょう. また,以下のような設定をすると 172.16.0.0/255.255.0.0上にあるサーバからの情報はキャッシュに入らなくなります. これは自サイトの情報をキャッシュに入れたくない場合に使える設定です.

acl localnet dst 172.16.0.0/255.255.0.0
no_cache deny localnet

その他,FTPについてはキャッシュに入れないなどといったことも 同じ要領で設定することが可能です.

賞味期限

はじめからキャッシュに入れない方法はわりましたが, ある情報がキャッシュの中で有効な期間を 短かくしたり長くしたりできないでしょうか. 特定のサイトの更新がめったにないことがわかっている場合, あるいはかなり頻繁に更新がかかる場合, そのような特定の条件に合わせた設定をしたくなることもあります. そうした調整はrefresh_patternによって実現することが可能です.

refresh_pattern <正規表現> <最小> <パーセント> <最大>

refresh_patternの書式は上の通りです. <正規表現>はURLにマッチさせるもので, これにマッチしたら続くパラメータを使って キャッシュにある情報が十分に新しいかどうかを検証します.

最終更新              要求1       要求2
   |                    |          |
---v--------------------v----------v------> 時刻
    \                  / \        /
     `----------------'   `------'
          LM_AGE             AGE

Squidは要求を受けつけるとまずキャッシュ中に 対応する情報があるかどうかを探します. なかったら実際のサーバにアクセスし, 得られた情報をクライアントに渡すとともに キャッシュに格納します. 図中の要求1がそのケースだと考えてください. 対して,キャッシュに情報がある場合(要求2)には それが十分に新しいかどうかを調べ, 十分に新しければキャッシュ中の情報をクライアントに渡し そうでなければ改めてサーバへのアクセスを行います.

十分新しいかどうかは次のようにして判断されます.

  1. Expiresで指定された日時をすぎていない → 新しい

    すぎている → 古い

  2. 図中AGEにあたる時間が<最大>をこえている → 古い

    こえていなければ次へ

  3. AGE/LM_AGE<パーセント>をこえていない → 新しい

    こえている → 古い

    最終更新時刻がわからない場合には次へ

  4. AGE<最小>をこえていない → 新しい

    こえている → 古い

デフォルトでは以下のような設定がなされています. 最後の行はすべてのURLにマッチする設定になっていますから 必要ならこの行の前に設定を入れるとよいでしょう. またすべてのケースについて調整をしたければ この最後の行を書き換えるとよいでしょう.

refresh_pattern ^ftp:         1440    20%     10080
refresh_pattern ^gopher:      1440    0%      1440
refresh_pattern .             0       20%     4320

最後に

かなりかけ足の解説となってしまいましが, Squidにはここでの解説では足りないくらい もっとたくさんの機能があるのです. 大きなものとしてはSquid同士を連携させて キャッシュを共有することなどがありますし, 要求されたURLを別のURLに書き換えてしまうことも可能です.

紙面の都合上,ここでは解説できませんでしたが 運用しながらそうした便利で強力な機能をさぐってみるのはどうでしょうか.


*1squid.confにおいては #以降がコメントとして扱われます.