ELBとHTTPSとリダイレクトループ【cloudpack 大阪 BLOG】

 httpでのアクセスをhttpsにリダイレクトしたいシーンがあると思いますが、AWSなどの環境上で構成を意識せずApacheなどのWebサーバにリダイレクト設定をしてしまうと意図せずリダイレクトループを起こしてしまうことがあります。
 今回はhttpでのアクセスをhttpsにリダイレクトした際に起こりやすいリダイレクトループとなる状態を意図的に作ってみたいと思います。
 

 1.環境の準備

下記の構成でサーバを準備します。詳細な設定方法は省略。

 

       [構成図] 

       f:id:cloudfish:20150829123348p:plain

 

 ① ELB
  ポートの設定
    80 → 80
   443 → 80

   SSL通信用に自己署名証明書を組み込んでおいてください。

 ②EC2インスタンス

   Apacheをインストールし適当なテストページを作成しておいてください。
  今回は「/var/www/html」をDocumentRootとしtest.htmlというページがあるものとします。

       [テストページ]  

  f:id:cloudfish:20150829235120p:plain

ここまで表示できれば準備完了です。 

 

2.リダイレクト設定

 次にリダイレクトをhtaccessに設定をしましょう。
.htaccess」ファイルを「/var/www/html」直下に作成し下記を記載してください。
httpでのアクセスをhttpsにリダイレクトする設定になります。
 ※この設定はconfファイルに設定しても問題ありません。

 
  [.htaccessの設定]

      f:id:cloudfish:20150829135100p:plain

 上記の設定が完了したら再度「http://[URL]/test.html」を表示させてみましょう。

 下記のようなページが表示されればリダイレクトループされています(chromeの場合)

  [テストページを再表示]

  f:id:cloudfish:20150829135928p:plain

       

3.なぜリダイレクトループが起こるのか?

 リダイレクトループが起こる仕組みを下図で示します。

f:id:cloudfish:20150830001216p:plain

①ブラウザからhttp(80)でアクセス

②ELBはhttp(80)で受信した通信をEC2にhttp(80)で渡す

③EC2のApacheのリダイレクト設定でhttps(443)でアクセスするようリダイレクトする

④ブラウザはhttps(443)でアクセス

⑤ELBはhttps(443)で受信した通信をEC2にhttp(80)で渡す

⑥③と同じ

 :

 以下ループ

 

ブラウザから https(443)でアクセスされてもELBからEC2へはhttp(80)で通信するため、Apache側ではhttp(80)で通信されたものとしてリダイレクトしてしまいます。ELBなどを利用しない環境では上記設定で問題なく動作するのでAWSへ移行する際注意が必要です。

4.対処方法

 上で設定した「.htaccess」を下記のように記載するとリダイレクトループが回避され、意図通りに動作します。

f:id:cloudfish:20150830003021p:plain

  「X-Forwarded-Proto」はブラウザがサーバー(ELB)への接続に使用したプロトコル(http or https)を判別することができます。

 

それでは、もう一度「http://[URL]/test.html」にアクセスしてみましょう。
通信プロトコルhttpsとなり正しくリダイレクトされているのが分かります。

f:id:cloudfish:20150830002700p:plain