httpでのアクセスをhttpsにリダイレクトしたいシーンがあると思いますが、AWSなどの環境上で構成を意識せずApacheなどのWebサーバにリダイレクト設定をしてしまうと意図せずリダイレクトループを起こしてしまうことがあります。
今回はhttpでのアクセスをhttpsにリダイレクトした際に起こりやすいリダイレクトループとなる状態を意図的に作ってみたいと思います。
1.環境の準備
下記の構成でサーバを準備します。詳細な設定方法は省略。
[構成図]
① ELB
ポートの設定
80 → 80
443 → 80
②EC2インスタンス
Apacheをインストールし適当なテストページを作成しておいてください。
今回は「/var/www/html」をDocumentRootとしtest.htmlというページがあるものとします。
[テストページ]
ここまで表示できれば準備完了です。
2.リダイレクト設定
次にリダイレクトをhtaccessに設定をしましょう。
「.htaccess」ファイルを「/var/www/html」直下に作成し下記を記載してください。
httpでのアクセスをhttpsにリダイレクトする設定になります。
※この設定はconfファイルに設定しても問題ありません。
[.htaccessの設定]
上記の設定が完了したら再度「http://[URL]/test.html」を表示させてみましょう。
下記のようなページが表示されればリダイレクトループされています(chromeの場合)
[テストページを再表示]
3.なぜリダイレクトループが起こるのか?
リダイレクトループが起こる仕組みを下図で示します。
①ブラウザから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」を下記のように記載するとリダイレクトループが回避され、意図通りに動作します。
「X-Forwarded-Proto」はブラウザがサーバー(ELB)への接続に使用したプロトコル(http or https)を判別することができます。
それでは、もう一度「http://[URL]/test.html」にアクセスしてみましょう。
通信プロトコルがhttpsとなり正しくリダイレクトされているのが分かります。