.htaccessで、ユーザエージェントが空白の訪問者を弾く。

ユーザエージェントが設定されていない訪問者はたぶん何かしら碌でもないことを考えている奴なので、ウェブサイトにアクセスできないようにしてやりましょう。

.htaccessに、以下のように記述。

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^-?$
RewriteRule ^.*$ - [F]

リクエストされたURIを書き換えずに "403 Forbidden" を返します。

Forbidden ではなくて "404 Not Found" を返したい時は、最後のフラグを以下のように変えます。

RewriteCond %{HTTP_USER_AGENT} ^-?$
RewriteRule ^.*$ - [R=404,L]

リクエストされたURLを書き換えずに、404ステータスコードを返して評価終了。

…なのですが、.htaccessで ErrorDocumentディレクティブを「ファイルを表示する」設定にしていると、403、404のいずれの場合でもリダイレクトループが発生することがあります。

これ、かなりハマったのですが、例えば「空のユーザエージェントを持つ訪問者には 404 を返す」という場合:

# (1) 404のとき、Apache標準のメッセージを表示。無事に動作する。
ErrorDocument 404 default

RewriteCond %{HTTP_USER_AGENT} ^-?$
RewriteRule ^.*$ - [R=404,L]
# (2) 自前のメッセージを表示。これも大丈夫。
ErrorDocument 404 "404 Not Found."

RewriteCond %{HTTP_USER_AGENT} ^-?$
RewriteRule ^.*$ - [R=404,L]
# (3) 自前のファイルを表示。
# 404.html に影響を及ぼす場所にこの.htaccessが設置されているとリダイレクトループが発生する。
ErrorDocument 404 /404.html

RewriteCond %{HTTP_USER_AGENT} ^-?$
RewriteRule ^.*$ - [R=404,L]

ErrorDocumentについてApacheの公式ドキュメントに当たってみると、

問題やエラーが発生したときの動作として、 Apache には以下の四つのうち一つの動作を設定することができます。

  1. Apache 標準の簡単なエラーメッセージを表示
  2. 自分で指定したメッセージを表示
  3. 問題やエラーの処理をする為に、自サーバ内の URL-path へリダイレクト
  4. 問題やエラーの処理をする為に、外部の URL へリダイレクト

…と書いてある。つまり (3) の場合、ユーザエージェントが空のとき404を発行 → ErrorDocumentの設定に従って 404.html にリダイレクト → リダイレクト先で .htacsess 制御発動 → ユーザエージェントが空なので404 → 以下続く… というループに陥ってしまうようですね。

こんなの気づかないって。

リダイレクトループを解消するには幾つか方法があると思いますが、一番手っ取り早いのは

ErrorDocument 403 default
ErrorDocument 404 default

とか、

ErrorDocument 404 '404 Not Found. Go to <a href="//あなたのドメイン.com">Top Page</a>.'

としておく(=ファイルを読む設定にしない)ということですか。

カテゴリ: