テクノロジー
Apacheトレイリングスラッシュが無い場合のhttpsリダイレクト
やりたいこと
タイトルの通り。
ApacheはDirectorySlashディレクティブにより、リクエストURLがディレクトリとなっていてスラッシュが無い場合はスラッシュを加えてリダイレクトする。
DirectorySlashディレクティブはデフォルトでオンになっている。(参考)
httpでアクセスがあった場合はhttpでリダイレクトする挙動となるため、以下の課題が発生する。
課題
以下の構成でApacheへアクセスする。
- 前提
- Cloudfrontへのhttpアクセスはhttpsリダイレクト
- Cloudfront及びALBまではhttps
- EC2まではhttp
トレイリングスラッシュ付きの場合は以下のようになる。
- 社内PCからCloudfront
- CloudfrontからALB
- ALBからEC2
トレイリングスラッシュが無い場合は以下のようになる。
- 社内PCからCloudfront
- CloudfrontからALB
- ALBからEC2
- EC2でリダイレクト(スラッシュ付与)
- Cloudfrontでhttpsリダイレクト
- CloudfrontからALB
- ALBからEC2
このように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"
- 社内PCからCloudfront
- CloudfrontからALB
- ALBからEC2
- EC2でhttpsリダイレクト(スラッシュ付与)
- CloudfrontからALB
- ALBからEC2
おまけ
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月時点の内容です。