テクノロジー

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

やりたいこと

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

課題

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

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

apache1

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

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

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

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

◆アクセスした際の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を再起動して再度確認。

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

apache3

◆アクセスした際の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月時点の内容です。

テクノロジーの記事一覧
タグ一覧
TOPへ戻る