AWS常時SSL リダイレクトループしない.htaccessの書き方

HTTPSを強制するために .htaccess に細工をするのは有名。例えば以下のような書き方が王道。

これをそのままElasticBeanstalkにデプロイするとリダイレクトループが発生する。正確に書くとリバースプロキシ(ロードバランサ)が有効になっている場合にリダイレクトループが発生する。

原因

原因についてはココが詳しい。ざっくりまとめると、

  • ロードバランサが443へのアクセスを80へのアクセスに変換する
  • .htaccess内の RewriteCond ${HTTPS} が永遠に on にならず、リダイレクトの度にRewriteRule が走ってしまう

元々のアクセスが https か http のどちらかが分かれば良いのだが、上記の挙動のせいで、https にリダイレクトしたとしても http からアクセスされたことになり、これが永遠に繰り返されてしまう。

解決策

(記事主さんが)無茶苦茶泥臭く挙動を追跡したところ、ロードバランサに到着した元のアクセスが http のときに限り、X-Forwarded-Proto というヘッダが付与され値が入るらしい。なので、X-Forwarded-Protoヘッダの内容を http か https かの判断基準にすれば良い、というのが基本的なアイデア。本人も言っているが、it’s just an empiric result… である。

その .htaccess が以下

これを ElasticBeanstalkにデプロイすると見事に動作する。

開発環境との共存

開発もAWSで行っていればこれで良いのだがそうでない場合も多いと思う。
上記のAWS用.htaccessを非AWSな開発環境に持ってくると今度は RewriteCond %{HTTP:X-Forwarded-Proto} !https が常に真になり、リダイレクトループが発生する。

あっちが立てばこっちが立たない!

いろいろ試行錯誤した結果、以下なら両立できた。(2017/7/8訂正)

根拠となる X-Forwarded-Proto がとっても経験的!なので、いつの日か使えなくなる日が来るかもしれない。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする