Apacheにてワーム等のログを記録しないようにする

Apache-UsersML(http://www.apache.jp/misc/announcelist.html) を読んでいるとたまーにワームのログを心配する質問ポストがある。超FAQなんだけど、対策をまとめた良いページって知らない。
ワームのログを分離する方法には2つある。

  • SetEnvIfでワームのアクセスパターンを設定する方法
  • 名前ベースのVirtualHostを設定する方法

検索をかけると、SetEnvIfを使う方法がよく紹介されているけど、これは以下の理由でおいしくない。

  • 新しい種類のワームが出るたびに設定が必要
  • 実際にアクセスが来てからでないと検知できない
  • 簡単な記述では完全に排除できない(大雑把に言うとPOSTで送られる類)

そこで、名前ベースのVirtualHost(以下名前ベースのVHostまたは単にVHostと書く。IPベースのVHostは普通の人には不要なので考えない)を設定する方法を。この方法の利点・欠点は下記の通り。

  • Host:ヘッダを送ってこないクライアントを全てワームと見なす。
  • だからワームのログは完全に排除できる。
  • そのかわり、Host: ヘッダを送ってこないクライアントのログの記録に難がある。

名前ベースのVHostは、クライアントのWebブラウザが送ってきてくれるHTTPリクエストヘッダの1つ、Host:ヘッダを使っている。詳しい説明はしないけど、Webホスティングサービス等でごく当たり前に使われているVHost技術はもうずいぶんと枯れていて、Host:ヘッダを送ってこないWebブラウザはもはやないと言って良い。

NameVirtualHost *

    ServerAdmin webmaster@example.com
    ServerName _default_
    DocumentRoot /www/_default_/htdocs
    ErrorLog /www/_default_/logs/error_log
    CustomLog /www/_default_/logs/access_log combined


    ServerAdmin webmaster@example.com
    ServerName www.example.com
    DocumentRoot /www/example.com/htdocs
    ErrorLog /www/example.com/logs/error.log
    CustomLog "|/usr/local/apache/bin/rotatelogs \
    /www/example.com/logs/access-%Y-%m-%d.log 86400 540" combined

設定は概ねこんなところ。Host:ヘッダを送信しないクライアントのアクセスは ServerName _default_ と記述した所のVHost設定にひっかかり、Host:ヘッダに www.example.com を送ってきた(正しい)クライアントは2つめのVHost設定にひっかかる。ついでにアクセスログはlogrotate.dに任せるよりも上記のようにApache付属のrotatelogsを使うほうが楽だ。何も考えずに確実にrotateしてくれる。(logrotate.dを使うと何らかの形でApacheを再起動する必要がある)
これで

  • 正しいクライアントのアクセス
  • ワームらしいログ+Host:ヘッダを送ってこないクライアント

この2つのアクセスログ分離が出来た。上記の例で /www/_default_/logs/access_log に記録しているログは必要であればとっておけば良いし、消しても良い。好きにできる。

(もはやないと思うが)Host:ヘッダを送ってこないクライアントに対応したければ、_default_のVHost設定の中で

ErrorDocument 404 /404.html

などと書き、404.html の中に「Host:ヘッダ送ってきて下さい」とでも書けば良い。/www/_default_/htdocsの中に404.html以外に何も置かなければどんなURIでも404.htmlの内容が送られることになり、人間によるアクセスであれば案内を読ますことが出来るというわけだ。

なんならwww.example.comのVHostと同じドキュメントルートを読ませても良い。とにかくHost:ヘッダを送ってこないクライアントのログを取らないこと、これに尽きる。

ここ2年以上この設定で動かしているが不具合はただの一度もない。Host:ヘッダを送って来ないクライアントのアクセスを受け付けた事もない。使うドメイン名は1つだからVHostなんていらない、などと言わずVHostにすることを薦めますよ。とっても。安定。