mod_access のハマりどころ
今回は、4-5 年 MT でブログやっていても、しょせんサーバに関してはシロート、という自分がハマったポイントを紹介します。
Apache の mod_access モジュールの「上書き」って把握してる? という記事です。
レンタルサーバで、.htaccess に order allow,deny
などと書いてアクセス制限をしている人は、ちょっと復習のために、ぜひともご覧ください。
状況の例
さて、こんなディレクトリ構造で、
/public_html
`--foo
|--.htaccess
`--bar
|--.htaccess
`--baz
`--.htaccess
こういう状況だったとします。
- foo, bar, baz という 3 つの階層がある
- 深い階層に行くほど負荷がかかる CGI を設置している
- そのため、深い階層に「行儀の悪いボット」は来て欲しくない
- バ──「千度」「万度」「億度」というボットに悩まされている
- 数字が増えるほど凶悪で、「億度」は最悪(一日一億回アクセス)
- (この記事はフィクションであり、団体名および以下略)
- foo, bar, baz それぞれのディレクトリに .htaccess を設置
- mod_access モジュールでアクセス制限を行う
- foo は億度、bar は万度、baz は千度を遮断したい
──ああ、「httpd.conf に設定書けよ」というツッコミには、「レンサバなのでルート権限なし」と答えておきます。
もはや「DDoS攻撃」!
それぞれの階層にある .htaccess に、次のような記述をしたとします。
#### foo/.htaccess
# 億度ボット、逝ってよし。
SetEnvIf User-Agent "yiyi" yiyidu-bot
order allow,deny
allow from all
deny from env=yiyidu-bot
#### foo/bar/.htaccess
# 万度ボット、氏んでくだたい。
SetEnvIf User-Agent "wandu" wandu-bot
order allow,deny
allow from all
deny from env=wandu-bot
#### foo/bar/baz/.htaccess
# 千度ボット、というか百 ううん、なんでもないの。
SetEnvIf User-Agent "qiandu" qiandu-bot
order allow,deny
allow from all
deny from env=qiandu-bot
よくある、UA で見分けて制限、という感じ。ちなみに、「アレ」は UA だけじゃ弾けませんぞ……。
問題点
さて、先ほどの .htaccess 設定には問題があること、わかりましたか?
じつは、上記のように設定すると、
一番アクセスして欲しくない foo/bar/baz/ ディレクトリに、最悪の「億度」がアクセスできる
──のです!
肝心の baz ディレクトリは、(比較的おとなしい)「千度」ボットだけがアクセスを拒否されます。
同様に、bar は「万度」、foo は「億度」だけがアクセス拒否になります。
仕様を知る
感覚的に、
「一番上の階層で拒否しているのだから、下層ディレクトリにはアクセスできないだろう」
と思っていたのですが、じつは、mod_access(など)の設定は、
下層ディレクトリの設定で上書きされる
という仕様になっているのです!
このあたりは、Apache のマニュアルをぼんやり眺めていても気付きにくい……。
Apache HTTP Server Version 1.3: Apache module mod_access
Apache HTTP Server Version 2.0: Apache module mod_access
まずはApache の「上書き」ディレクティブ(命令)について知っておくべきでした。
mod_access の説明は、下記のページが凄くわかりやすくて、かなり参考になります。
Apache入門:アクセス制限:アクセス制限の記述(Order, Allow, Deny)
ディレクトリに対するアクセス制限の設定の場合は、指定したディレクトリ及び全てのサブディレクトリが対象となります。例えばサブディレクトリに対して別のアクセス制限の設定を行った場合には下位のディレクトリに対する設定によって上書きが行われていきます。
──とまぁ、いつものように、知っている人には「ごく当たり前のこと」を書いていますが、まだまだ覚えることが多く、苦しくも楽しいです。
つぶやき
というか、いっそのこと
order allow,deny
allow from all
deny from .cn # ちう☆ごく
deny from .kr # こりゃ~
──で済めばいいのですがね……。
(いちおう書いておくと、上記の設定で .cn, .kr ドメインからのアクセスは遮断できる──けど、ご利用は計画的に)
(でもまぁ、個人のサイトなら、日本語圏以外のアクセスは全遮断、という選択肢もアリかなぁ……)