2022/09/02

テクノロジー

Apacheトレイリングスラッシュが無い場合のhttpsリダイレクト

この記事の目次

    やりたいこと

    タイトルの通り。
    ApacheはDirectorySlashディレクティブにより、リクエストURLがディレクトリとなっていてスラッシュが無い場合はスラッシュを加えてリダイレクトする。
    DirectorySlashディレクティブはデフォルトでオンになっている。(参考)
    httpでアクセスがあった場合はhttpでリダイレクトする挙動となるため、以下の課題が発生する。

    課題

    以下の構成でApacheへアクセスする。

    • 前提
      • Cloudfrontへのhttpアクセスはhttpsリダイレクト
      • Cloudfront及びALBまではhttps
      • EC2まではhttp

    トレイリングスラッシュ付きの場合は以下のようになる。

    トレイリングスラッシュが無い場合は以下のようになる。

    このようにhttpsでアクセスしたものが、DirectorySlashによりhttpにリダイレクトされてしまう。

    ◆ブラウザでアクセスした結果

    ◆アクセスした際のApacheアクセスログ

    [31/May/2022:20:04:06 +0900] "GET /test HTTP/1.1" 301 260 "-" "Amazon CloudFront"
    [31/May/2022:20:04:06 +0900] "GET /test/ HTTP/1.1" 200 52 "-" "Amazon CloudFront"

    これを解消するために、Apache側でスラッシュを付与して更にhttpsでリダイレクトする設定を行う。

    設定

    Apacheのconfファイルに以下を追記する。

    RewriteCond %{LA-U:REQUEST_FILENAME} -d
    RewriteRule ^/(.*[^/])$ https://%{HTTP_HOST}/$1/ [R=301,L,QSA]

    この設定はDirectorySlashより優先される。
    Apacheを再起動して再度確認。

    ◆ブラウザでアクセスした結果

    ◆アクセスした際のApacheアクセスログ

    [31/May/2022:20:22:27 +0900] "GET /test HTTP/1.1" 301 261 "-" "Amazon CloudFront"
    [31/May/2022:20:22:27 +0900] "GET /test/ HTTP/1.1" 200 52 "-" "Amazon CloudFront"

    おまけ

    ApacheのRewriteCondではフロントがhttpsの時という条件を書くことができる。
    例えば、Cloudfront,ALBがhtttpsで受けているかの判定は以下のように記載する。
    ※ALBは自動で付与されるが、Cloudfrontはビヘイビアでヘッダーの設定をする必要がある。

    # Cloudfront
    RewriteCond %{HTTP:CloudFront-Forwarded-Proto} =https
    # ALB
    RewriteCond %{HTTP:X-Forwarded-Proto} =https
    RewriteCond %{LA-U:REQUEST_FILENAME} -d
    RewriteRule ^/(.*[^/])$ https://%{HTTP_HOST}/$1/ [R=301,L,QSA]

    ・RewriteCondに関するオンプレからAWS移行時の注意点
    オンプレ環境でLB(https)→サーバ(http)としており、LBで付与したヘッダーをRewriteCondで使用している場合、上で記載したようにAWS(Coudfront,ALB)が付与するヘッダーとは異なる可能性がある。

    ※本記事は2022年09月時点の情報です。

    著者:マイナビエンジニアブログ編集部