読者です 読者をやめる 読者になる 読者になる

続 カッコの付け方

AWSを始めとしたクラウドコンピューティング全般と、唯一神emacsにおける()の付け方についてだらだら書きます

AWS ELB + SSL Termination下でEC-CUBEを正しく動かす

AWS ELB SSL Termination EC-CUBE

EC-CUBEAWS上で運用するとき、良くある構成

f:id:iga-ninja:20150726081412p:plain

今回の構成は SSL Termination を行い、ELB -> EC2(Webサーバ)間ではHTTPS(443)通信を行いません。この場合、EC2側は常にHTTP(80)で通信を受けるので、ユーザーのELBに対するアクセスがHTTPなのかHTTPSなのか普通の方法では判断出来ません。

X-Forwarded-[xxx]ヘッダ

ELBを通過するときに、X-Forwarded-Port/Proto等のヘッダが付きます。これを判別することにより見分けることが出来ます。 http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/x-forwarded-headers.html

EC-CUBE内部におけるHTTPS判定

EC-CUBEに対してGREPかけると

./data/module/Net/URL.php:            $this->protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http');
./data/module/Net/URL.php:            case 'https':   return 443;
./data/class/util/SC_Utils.php:        if (SC_Utils_Ex::sfIsHTTPS()) {
./data/class/util/SC_Utils.php:            $proto = "https://";
./data/class/util/SC_Utils.php:            $domain  = SC_Utils_Ex::sfIsHTTPS() ? HTTPS_URL : HTTP_URL;
./data/class/util/SC_Utils.php:     * HTTPSかどうかを判定
./data/class/util/SC_Utils.php:    function sfIsHTTPS () {
./data/class/util/SC_Utils.php:        // HTTPS時には$_SERVER['HTTPS']には空でない値が入る
./data/class/util/SC_Utils.php:        // $_SERVER['HTTPS'] != 'off' はIIS用
./data/class/util/SC_Utils.php:        //if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
./data/class/util/SC_Utils.php:        #if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
./data/class/util/SC_Utils.php:        if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
./data/class/util/SC_Utils.php:        } else if(ereg("^https://", $istr)) {
./data/class/util/SC_Utils.php:            $head = "https://";

このように方方で$_SERVER['HTTP']で判定しています。これらをすべて $_SERVER['HTTP_X_FORWARDED_PROTO']に変換していくのは至難の業です。
じゃあどうするか。無い変数はつけてしまえばいいです。

mod_setenvif

apacheモジュールで setEnvIfというのがあります。これを使って$_SERVER変数を無理やり追加します。

SetEnvIf X-Forwarded-Proto ^https$ HTTPS=on

リダイレクトで片っ端からSSLにする

SetEnvIf X-Forwarded-Proto ^https$ HTTPS=on

RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

せっかく HTTPS変数にするんだから、そいつを使えばいいと考えるなら、RewriteCondで HTTP:HTTPSを指定すること。

もう一つの解法、ソースをちょっといじって解消する

https://forge.typo3.org/issues/29693

f ($_SERVER['X-Forwarded-Proto'] == 'https') {
    $_SERVER['HTTPS'] = 'on';
}

phpの初手でこいつをかませばいい。

まとめ

  • EC-CUBEHTTPS判定は、サーバ変数 $_SERVER['HTTPS']
  • HTTPS -> X-Forwarded-Protoに判定をまるっと変えるようなconfigはない
  • SetEnvIfで HTTPSサーバ変数を付与するのが楽

X-Forwarded-Protoでリダイレクトだけかけても、商品をカートに入れるときにエラーが出ます。これの対処方法がわからない場合、参考に。 ちなみに、EC-CUBEはセッションをDBに保存するらしいので、(デフォルト) StickySessionは必須ではないはず。