今回は、先日書籍(Amazon Web Servicesクラウドデザインパターン設計ガイド)が発売されたCloud Design Pattern(CDP)の記事になります。
対象は「Multi Load Balancerパターン」です。
ELBのSSL Termination機能で、SSLの処理をEC2(Webサーバ)ではなくELBに行わせることが可能ですが、それに伴い、このパターンの「注意点」に下記の記載があります。
ELBのSSL Termination機能を用いるとEC2側はHTTPでリクエストを受けることになるのでアプリケーションでのHTTPS接続の判定が難しくなる。
直接EC2のWebサーバでSSLの設定をして、HTTPSでのアクセスを行う場合はPHPの場合、下記の環境変数でHTTPSの接続かどうかチェックしている場合が多いとお思います。
($_SERVER[“HTTPS”]の有無でチェック)
しかし、これをELBのSSL Termination機能でSSLの処理をELB側で行うとHTTPSのアクセスは、ELBでHTTPになりEC2にはHTTPでアクセスされることになります。
この場合、上記の環境変数(HTTPS)はセットされません。
これにより、アプリケーション側のHTTPSのチェックもHTTPSではない(HTTPで接続)と判断され、挙動が変わってしまいます。
(HTTPSへのリダイレクトループが多いです)
では、アップリケーションはHTTPSかどうかのチェックを行う事ができないかというとそうではなく、以前、ELBの”SSL Termination”を利用したときのHTTPヘッダの記事で紹介した通り、ELBのはEC2にリクエストを渡す時、下記のようなX-Forwarded-Xxxといったヘッダを付与する事ができます。
ということで、PHPの場合は$_SERVER[“HTTP_X_FORWARDED_PROTO”]の値がhttpsかどうか(HTTPの場合はhttp)でチェックすればよいことになります。
また、アプリケーションを修正することができない場合も多々あると思います。
そのような場合は、下記のようにWebサーバ(Apache)の設定(httpd.conf)で環境変数をセットしてしまう方法も
あります。
SetEnvIf X-Forwarded-Proto https HTTPS=on
X-Forwarded-Protoがhttpsの場合は、クライアントはHTTPSでアクセスされているので、環境変数HTTPSをonとしてセットしています。
この場合、ELB経由のHTTPSのアクセスでも上記のようにEC2側で今まで同様、環境変数(HTTPS)がonにセットされるので、アプリケーションの修正無しに対応できる可能性は高いと思います。
($_SERVER[“HTTPS”]のみHTTPS接続のチェックをしている場合)
さらに、Webサーバの設定も変更できない、もしくは、上記の変更では対応できない($_SERVER[“HTTPS”]以外でHTTPSのチェックをしている)場合等もあると思います。
このような場合は、ELBでSSLの処理(SSL Termination)をした後に、再度HTTPS通信にして、EC2にリクエストすることも可能です。
当然、EC2のWebサーバでSSLの設定を行っておく必要があります。
そして、この場合ELB経由でもEC2のWebサーバはHTTPSで接続されるので、直接EC2にHTTPSでアクセスする場合とアプリケーションはHTTPSのチェックに対して同様の挙動となるはずです。
ELBがEC2にリクエストを渡すときに、再度HTTPS通信にする方法は、下記のようにELB作成時に容易にできます。
まずはLoad Balancer ProtocolをHTTPSにするだけでなく、EC2への接続に関するInstance ProtocolもHTTPSにします。
そして、途中でEC2とのSSL処理に利用する証明書を設定する画面になります。
ここで設定するSSL証明書は、下記の設定ファイル(Apacheのhttpd.conf)等で設定されている、EC2上のWebサーバで利用しているものと同じものを設定します。
SSLCertificateFile /etc/pki/tls/certs/localhost.crt