AWS ELB配下でApacheのRewriteRuleが上手く動かなかった話
投稿日:
■環境
AWS ELB
AWS EC2
Apache 2.2.32
AWSのEC2上で動いているApacheサーバーでの話。
SEO対策で/index.html
を/
にリダイレクトしたかったので
.htaccess
に以下を設定しました。
RewriteRule ^(.*)index.html$ $1 [R=301,L]
検証インスタンスでは上手く動いたので、本番インスタンスにも反映させたところ
https://〜/index.html
(443ポート) が http://〜/
(80ポート)にリダイレクトされるようになってしまいました。
なんでだろう?と思いながら以下のような分岐を作ってみましたが、結果は変わらずでした。
# 一旦プロトコルはhttpとしておく
RewriteRule .* - [E=X_PRTCL:http]
# リクエストプロトコルがhttpsの場合、リダイレクト先もhttpsにする
RewriteCond %{HTTPS} on
RewriteRule .* - [E=X_PRTCL:https]
RewriteRule ^(.*)index.html$ %{ENV:X_PRTCL}://%{HTTP_HOST}/$1 [R=301,L]
なぜ443ポート(https)の通信が80ポート(http)扱いになってしまったかというと
本番環境のEC2はELBを通しているのが原因でした。
つまり、検証環境では
PC
↓443ポート
EC2
だったのに対して、本番環境では
PC
↓443ポート
ELB
↓80ポート
EC2
となっていたのでした。
ELBを経由した場合、HTTPプロトコルを判定するにはX-Forwarded-Proto
というパラメータを見る必要があるようです。
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/classic/x-forwarded-headers.html
以下のようにhtaccessへ記載すればELB経由でも上手く動きました
# 一旦プロトコルはhttpとしておく
RewriteRule .* - [E=X_PRTCL:http]
# リクエストプロトコルがhttpsの場合、リダイレクト先もhttpsにする
RewriteCond %{HTTPS} on [OR] # ELBを経由しない時用
RewriteCond %{HTTP:X-Forwarded-Proto} https # ELBを経由する時用
RewriteRule .* - [E=X_PRTCL:https]
RewriteRule ^(.*)index.html$ %{ENV:X_PRTCL}://%{HTTP_HOST}/$1 [R=301,L]