コンテンツにスキップ

mod_rewriteによるHTTPからHTTPSへのリダイレクト

mod_rewriteは、リクエストのURLパスやサーバー変数を規則に照合し、URLの書き換えや外部リダイレクトを行う。


mod_rewriteは、正規表現を使ってURLを書き換えるモジュールである。書き換え結果は、Apache内部で別のパスとして処理することも、クライアントへ外部リダイレクトとして返すこともできる。

HTTPからHTTPSへの移行では、ポート80のVirtualHostへ到着したリクエストからHTTPS URLを作り、301を返すために使う。


RewriteEngine Onは、その設定コンテキストで書き換えエンジンを有効にする。

mod_rewriteモジュールを読み込んだだけでは、個々のVirtualHostのルールは処理されない。ルールを置くVirtualHostで書き換えエンジンを有効にする。


RewriteRuleは、照合するパターン、置換先、処理方法を変えるフラグで構成される。

RewriteRule Pattern Substitution [flags]

ルールは記述順に評価される。前のルールによる書き換え結果が、後続ルールの入力になる場合がある。


VirtualHostに置いたRewriteRuleのPatternは、ホスト名とポートの後ろ、クエリ文字列の前にあるURLパスへ照合される。

^は文字列の先頭に一致するため、すべてのURLパスを対象にできる。

ホスト名、ポート、クエリ文字列はPatternの直接の対象ではない。必要な場合はHTTP_HOST、SERVER_PORT、QUERY_STRINGなどのサーバー変数を使う。


Substitutionは、Patternに一致したときの置換先を指定する。絶対URLとRフラグを組み合わせると、クライアントへ外部リダイレクトを返せる。

転送先を一つの正式なホスト名に統一する場合は、Substitutionの絶対URLへwww.example.comのように直接記述する。

%{HTTP_HOST}は、クライアントが送信したHostヘッダーの値であり、未登録のホスト名やポート番号が含まれる場合がある。検証せずにリダイレクト先へ使うと、クライアントがLocationヘッダーのホスト名を決められる。複数のホスト名を引き継ぐ場合は、許可する値を事前に限定する。

%{REQUEST_URI}は、リクエストされたURLのパス部分である。たとえば/docs/index.htmlのような値になる。

REQUEST_URIにはクエリ文字列を含まない。置換先で新しいクエリ文字列を指定しなければ、元のクエリ文字列は既定で引き継がれるため、QSAフラグは必要ない。


R=301は、書き換え結果をHTTPステータス301の外部リダイレクトとしてクライアントへ返す。

301は恒久的な移動を表し、ブラウザーや中間キャッシュに保存されることがある。応答結果はcurl -IなどでステータスとLocationヘッダーを確認する。


Lはlastを表し、このルールが適用されたら現在の書き換え処理で後続ルールを実行しない。

HTTPからHTTPSへのリダイレクトで応答を確定させ、同じVirtualHostにある別のルールが続けて処理されることを防ぐ。


RewriteCondは、直後のRewriteRuleを適用する追加条件を定義する。

HTTPとHTTPSを同じ設定範囲で扱う場合は、%{HTTPS}などを条件に使うことがある。ルールを<VirtualHost *:80>だけに置く場合は、そのVirtualHostへ到達する接続がHTTPに限定されるため、HTTPSかどうかを調べる条件は必要ない。


LogLevelは、モジュールごとのログレベルを指定できる。

LogLevel warn rewrite:trace2

全体の基準をwarnに保ちながら、mod_rewriteだけtrace2へ上げる指定である。traceレベルはログ量と処理負荷を増やすため、切り分け時だけ使用する。



  • mod_rewrite RewriteEngine、RewriteRule、サーバー変数、クエリ文字列の動作。

  • RewriteRule Flags R、Lなどのフラグ。