ミケネコ研究所 ミケネコ研究所 > htaccess リファレンス > リダイレクト

リダイレクト

ある条件にしたがって、別のリソースへのリダイレクトを提供します。


利用例


自作 404 not found メッセージ

間違った URL が呼び出されると、サーバは、

Not Found

The requested URL /~user/123456.html was not found on this server.


Apache/1.3.9 Server at www.mikeneko.ne.jp Port 80

このようなエラーメッセージを返します。または、Internet Explorer ユーザーで、「HTTP エラーメッセージを簡易表示する」チェックボックスを ON にしている人は、次のようなエラーメッセージが見えるでしょう。、

ページが見つかりません

検索中のページは、削除された、名前が変更された、または現在利用できない可能性があります。

次のことを試してください:

  • アドレス バーにページ アドレスを入力した場合は、ページ アドレスを正しく入力したかどうかを確認してください。

このような定型で味気のないメッセージの代わりに、自作のメッセージを表示できます。Not Found エラー用の HTML ファイルを作りましょう。ファイル名はなんでもよいのですが、404.html という名前で作ることにします。そして、http://(サーバ名)/~user/404.html という場所にアップロードした場合、Not Found エラーのたびにこのファイルを表示されるようにするには、.htaccess の ErrorDocument 命令によって、404.html の場所を指定します。

ErrorDocument 404 /~user/404.html

404 File not Found が発生したとき、サーバは、http://(サーバ名)/~user/404.html にあるファイルを探しに行き、あればそれを表示します。

(404.html の中身)

ファイルがないみたい

あなたのおかけになった URL は、現在使われておりません。

URL をお確かめになって、もう一度おかけ直し下さい。

日本人なら日本語のエラーを表示させたいと思うのは、自然なことでしょう。メッセージはお好きに編集して下さい。どういうわけか、この 404 not found メッセージを編集するとき、生まれてはじめてウェブを作成したときと似た感動が得られます。

しかしコンフィグレーションで 404.html を指定したのにもかかわらず 404.html が存在しなければ、いったいどうなるのでしょうか?(*) このときは、通常の 404 File not Found メッセージに加えて、「どうもコンフィグが狂っているようだ。」という旨のメッセージが併せて表示されます。

* : 上記の疑問がすぐに浮かんだ方は、危機管理力に優れているといえます。なぜなら 404 error → 404.html がない → 404 error → 404.html がない → … という無限ループの可能性があるからです。幸いにも Apache は、このような間抜けな循環を検出できます。

404 File not Found 以外のいろんなエラーに汎用的に対応させるには、

ErrorDocument 403 /~user/403.html
ErrorDocument 404 /~user/404.html
ErrorDocument 500 /~user/500.html

このように、複数を用意しましょう。エラーの大半は、404、403、500 ですので、この 3 つを設定しておけば大半のケースはカバーできます。

ErrorDocument を指定しない場合、エラーメッセージには「The requested URL /~lab/123456.html was not found on this server.」のように、間違った URL が動的に挿入されましたが、404.html のような静的なファイルではこういったことが表現できません。動的なメッセージを表示させたいのなら、CGI を使いましょう。

ErrorDocument 403 /~user/http_error.cgi?403
ErrorDocument 404 /~user/http_error.cgi?404
ErrorDocument 500 /~user/http_error.cgi?500

このように、エラー表示用の CGI スクリプトを自作すれば可能です。エラーメッセージ中にアクセスされたファイル名を表示したい場合は、環境変数 REQUEST_URI を取り出しましょう。

しかし、エラーが発生する度に CGI スクリプトが起動するのは、サーバ負荷の観点から言って、愉快な話ではありません。局所的にとどめるべきでしょう。

らくちんなサイト引越しメッセージ

サイトを引越しした際に、訪問者にどうやって移動してもらうかが問題になりますが、いくつかご紹介しましょう。

方法1:「このサイトは引越ししました。URL: 〜。」
シンプルでわかりやすい方法。いちいち新 URL をクリックするのは面倒だと感じることもある。
方法2:META タグで n 秒後にジャンプする。
自動的にジャンプするので、手間が省ける。方法1と併せて用いられることが多い。しかし、ブラウザのバックで戻った時に、また自動的にジャンプしてしまい、逆にわずらわしいこともあり、私は嫌いである。

上記の2方法は非常にポピュラーな手段であり、とくに不便もありません。が、次に .htaccess を用いた方法を紹介しましょう。

方法3:.htaccess の Redirect を用いる。
リダイレクト記述を行うと、瞬時にジャンプし、またブラウザ履歴に残りません。ブラウザのバックで戻っても再びリダイレクト元を表示することはありません。したがって、訪問者は「スムーズに移動」されますし、よほど注意深くないと「移動したことすら気づかない」でしょう。次は .htaccess の設定例です。
Redirect permanent /~user/hobby/ http://mydomain.jp/hobby/

このような指定を行うことで、http://旧ドメイン/~user/hobby/????? へのアクセスは、http://mydomain.jp/hobby/????? へリダイレクトされます。ディレクトリ構造を保ったままリダイレクトされるのが、この方法の利点です。

方法4:.htaccess の ErrorDocument を用いる。
旧サイト全体から HTML ドキュメントを撤去します。当然そこへのアクセスは 404 not found となりますが、not found メッセージを編集し、移動した旨を詳しく伝えます。この方法のメリットは、どんなにサイトが巨大になっていても、移動メッセージを1つ書くだけでよいことです。次は .htaccess の設定例です。
ErrorDocument 404 /~user/moved_Announcement.html

爆撃を撃ち返すオウム返し

ウェブ管理者であるあなたは、何気なく HTTP アクセスログを眺めていると、まさに今、この瞬間、自サイトが何者かに爆撃アクセスされている光景を目撃してしまいました! 同一ホストからのリクエスト頻度たるや、毎秒3〜10アクセス。人間技ではないために、礼儀をわきまえていないロボット(プログラム)であることは一目でわかります。こういったことはよくあることです。

さて、どういう対策をとりましょうか? まずはログから見える範囲で判断しましょう。相手が、あなたのサイトのリソース全てを洗いざらい取得する目的であれば、すべての HTML をお持ち帰りいただいた時点で爆撃はやむかもしれません。しかし、無限再帰下降していたり、どうも循環しているようであれば、対策を撃たなくてはなりません。放置しても、すぐにサーバが死んでしまうことはないかもしれませが、うっかりCGI スクリプトが連続起動されたりすると、リソースが急激に消費されてしまって、よからぬ事態になるかもしれません。

あなたのできることは、爆撃元の IP アドレスを取得し、アクセス制限を敷くことです。これで、すべて 403 forbidden となります。大量に飛んでくるリクエスト自体を防ぐことはできないのですが、リクエスト解析・サーバコンフィグの解析・リプライにかかる転送量・総接続数などなど、あなたの HTTP サーバの仕事量を大幅に減らすことができます。

とりあえずアクセス制限を敷いたら、IP アドレスから、相手の素性を調べることを試みましょう。ひょっとすると、Web が公開されていて、管理者のメールアドレスがあるかもしれません。また、爆撃されるような心当たりが、あなたにあるかもしれません。

アクセス制限を敷けば爆撃が収束に向かうことが多いのですが、依然として同じリソースに対しての爆撃が止まないときもあります。いい加減、相手に気づいてもらうにはどうすればよいのでしょうか。そのひとつとして、オウム返しという手段が考えられます。

ErrorDocument 403 http://20.30.195.128/ (← 爆撃元のIP アドレス)

これで、爆撃元のリクエストは、まずアクセス制限ではじかれて、次に爆撃元の 80 番ポート(HTTP)にリダイレクトされます。相手が毎秒 10 発の弾丸を撃ってくると、その要求はそっくり毎秒 10 発相手自身に向けられることになります。

この方法のよいところは、これが報復活動では決してないということです。殴られて殴り返したのなら、あなたも同罪に問われる可能性がありますが、今回の場合は単に

『 That is the route to follow. (順路はあちらですよ、お客さん。) 』

という立て札を立てたにすぎず、それ以上のことは何もしていないのです。悔し紛れの戦術ではなく、

「意識しているのかしていないのか私の知る所ではありませんが、
 あなたは非常に不可解な行動を取っています。」

と相手に知らせる重要なメッセージとなります。このオウム返しは、相手のネットワーク内のみのトラフィックを増加させ、その他のトラフィックを不必要に増加させません。

しかし相手は、このようなリダイレクトを無視する巧妙なプログラムかもしれません。全く爆撃がやむ様子がなければ、あなたのネットワーク管理者に連絡しましょう。ルーティングの時点で弾いてもらえます。

リダイレクトの危険性

ErrorDocumentRedirect では、リダイレクト先に外部 URL を指定できます。外部 URL が本当に外部のサーバを指定していれば問題はないのですが、外部 URL に自分のサーバを指定した場合、いとも簡単に無限ループに陥る可能性があります

例1: ErrorDocument を使った無限ループのコンフィグレーション

あなたは、次のようなコンフィグレーションを記述したとしましょう。

ErrorDocument 404 http://www.myserver.ne.jp/~user/error404.html

ErrorDocument 500 http://www.myserver.ne.jp/~user/error500.cgi

もしもこの .htaccess ファイルが www.myserver.ne.jp に置かれていたのであれば、無限循環する危険性があります。error404.html が実は存在していなかったり、また error500.cgi がなんらかの原因でエラーを吐くようになると、エラー → リダイレクト → エラー → リダイレクト → エラー → リダイレクト ・・・と、ブラウザとサーバの間に永久ピンポンが発生してしまいます。

この場合は、絶対に次のように書くべきです。

ErrorDocument 404 /~user/error404.html

ErrorDocument 500 /~user/error500.cgi

サーバ内のドキュメントを指定したり、サーバ内の CGI を指定するときは、このように / で始めましょう。これはリダイレクトではありません。仮に error404.html がない場合も、HTTP サーバがそれを判断できますので、無限循環にならないのです。

例2: Redirect を使った無限ループのコンフィグレーション

あなたは、

http://www.myserver.ne.jp/~user/〜 からのアクセスをすべて
http://www.myserver.ne.jp/~user/new/〜 にリダイレクトさせる

ようにしたくて、次のようなコンフィグレーションを記述したとしましょう。

Redirect /~user/ http://www.myserver.ne.jp/~user/new/

これはアウトです。実際に http://www.myserver.ne.jp/~user/ へアクセスすると、無限循環になります。循環している様子を、わかりやすく次に書いてみました。

ブラウザの要求: http://www.myserver.ne.jp/~user/
サーバの返答 : http://www.myserver.ne.jp/~user/new/ リダイレクトせよ
ブラウザの要求: http://www.myserver.ne.jp/~user/new/
サーバの返答 : http://www.myserver.ne.jp/~user/new/new/ リダイレクトせよ
ブラウザの要求: http://www.myserver.ne.jp/~user/new/new/
サーバの返答 : http://www.myserver.ne.jp/~user/new/new/new/ リダイレクトせよ
ブラウザの要求: http://www.myserver.ne.jp/~user/new/new/new/
(無限・・・)

このように、リダイレクト後の URL も /~user/ にマッチしているのが原因です。外部 URL に自サイトを指定すると、常に循環の危険がつきまといます。

循環の間、はじめに http://www.myserver.ne.jp/~user/ へのアクセスを開始したブラウザにとってみれば、画面右上の地球マークがぐるぐると回っている(**)ばかりだけであり、なんだか全然つながらないなぁ・・と疑問に思うだけです。この間、ブラウザとサーバとの永遠なるピンポンが発生していることには気づかないでしょう。私のローカルサーバで実験したところ、実に毎秒10回の循環が発生してしまいました。あなたがブラウザのストップボタンを押せば、そこでピンポンは中断されます。

Redirect の場合は安全な代替手段がなく、この循環を検出することはできないので、あなた自身が細心の注意を払い、決して合わせ鏡のようなコンフィグレーションを記述しないようにして下さい。

** : ブラウザによっては、この表現は正しくありません。


リファレンス


ErrorDocument

ErrorDocument error-code document
# 例1: エラーの代わりに、サーバ内のドキュメントを表示する例。
ErrorDocument 403 /forbidden.html

# 例2: エラーの代わりに、指定されたメッセージを表示する例。
ErrorDocument 403 "403 Forbidden. Sorry :-("

# 例3: エラーの代わりに、指定された CGI を実行する例。
ErrorDocument 404 /cgi-bin/not_found.cgi

# 例4: エラーの代わりに、指定された外部 URL へリダイレクトさせる例。
ErrorDocument 500 http://user.com/cgi-bin/

HTTP ステータスが 4xx(クライアントエラー)や 5xx(サーバエラー)であった場合、標準のエラーコードを返す代わりに、上例のように、別のドキュメントを表示させたり、メッセージを表示させたりするように指示できます。

document がサーバ内のリソースを示すときは、スラッシュから始まるサーバ絶対パスでなければなりません。document が http:// で始まる外部サーバのリソースを示すときは、クライアントにはリダイレクトが送信されます。

Redirect

Redirect url-path url
Redirect status url-path url
Redirect /~user/ http://user.original.ne.jp/
Redirect permanent /~user/ http://user.original.ne.jp/

url-path のリクエストがあった場合、改めて url へアクセスするようにクライアントに返します。上記の例が施された設定では、サーバ内の /~user/info.html にリクエストが合った場合、別サーバの http://user.original.ne.jp/info.html を探すようにクライアントに伝えます。

url-path は絶対パスで記述しなければなりません。

引数 status はオプションです。status を指定すると、クライアントにリダイレクトの理由を伝えることができます。省略時は temp です。status の種類は以下のとおりです。

Redirect permanent
301 Moved Permanently ステータスが返されます。リソースが、すでに別の場所へ移動したことを伝え、今後はそちらへリクエストするよう促します。
Redirect temp
302 Moved Temporarily ステータスが返されます。リソースが、一時的に移動していることを伝え、今後も今の URL でリクエストしつづけるよう促します。デフォルトです。
Redirect seeother
303 See Other ステータスが返されます。リソースが、通常に移動された時に使用します。
Redirect gone
410 Gone ステータスが返されます。リソースが、恒久的に移動し url パラメータを省略した時に使用します。

RedirectTemp

RedirectTemp url-path url
RedirectTemp /~user/ http://user.original.ne.jp/

Redirect と同じくリダイレクトを提供しますが、クライアントには、常に 302 Moved Temporarily ステータスが返されます。Redirect temp と同義です。

RedirectPermanent

RedirectPermanent url-path url
RedirectPermanent /~user/ http://user.original.ne.jp/

Redirect と同じくリダイレクトを提供しますが、クライアントには、常に 301 Moved Permanently ステータスが返されます。Redirect permanent と同義です。


ミケネコの htaccess リファレンス http://mikeneko.creator.club.ne.jp/~lab/web/htaccess/