fbpx

メニュー

CloudFlareのFlexible SSLでWordPressがぶっ壊れた

高橋文樹 高橋文樹

この投稿は 10年 前に公開されました。いまではもう無効になった内容を含んでいるかもしれないことをご了承ください。

CDNサービスであるCloudFlareには有償プランがあって、その機能の一つにFlexible SSLというのがあります。

これは図の通り、自分のWebサーバにSSLが入っていなくても、httpsのアクセスに限りCloudFlare側が勝手に証明書を提供してくれるというものです。

SSL利用の本来の目的はユーザーから提供される情報の送信を保護することなので、全部SSLで保護しないと意味ないような気もしますが、とにかくブラウザ上はあの緑の鍵(iPhoneだとグレーの鍵)マークが出せるわけですね。

で、このFlexible SSLなのですが、これを利用するとWordPressのある機能が動かなくなります。それはSSL通信が行われているか否かを判定する is_ssl という関数です。

この関数は$_SERVER変数を見てSSLか否かを判定しているんですが、Flexible SSLを利用している場合、CloudFlareからは通常のポート80でリクエストが飛んでくるので、常にfalseとなります。

この結果、SSLを必須とするようなプラグインや管理画面をSSLに制限する機能を使っていたりすると、リダイレクトループが発生します。

  1. CloudFlare経由でhttps://takahashifumiki.com/login/ にアクセス
  2. is_sslは常にfalseなので、プラグインが勘違いしてhttps://takahashifumiki.com/login/ にリダイレクト
  3. 無限ループ

このような仕様であるからこそ、さくらのレンタルサーバーみたいなしょぼいプランでも独自SSLが使えたりするわけなんですが。

対処法

ではどうすればいいかというと、CloudFlareはFlexible SSLの場合、HTTP_X_FORWARDED_PROTO というヘッダーを送ってきます。このヘッダーがhttpsとなっている場合はSSL通信ということになるので、wp-config.phpに判定式を書き、SSLかどうかを設定してあげます。

// CloudFlareのSSL対応
if( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 'https' == $_SERVER['HTTP_X_FORWARDED_PROTO'] ){
        $_SERVER['HTTPS'] = 1;
        $_SERVER['SERVER_PORT'] = 443;
}

こういったグローバル変数を書き換える処理はあまり好ましくないのですが、取り急ぎこれで is_ssl は正しく動くようになります。

ポイントはSSLであろうがなかろうがポート80で飛んで来て一つのバーチャルホストで処理するということですね。

以前は違う仕様だったような気もするのですが……ログインできなくなっててビックリしました。

CloudFlareのProプランは月20ドル、1サイト追加ごとに月5ドルと考えると、コスト的には微妙ですが、証明書ってわりと切れちゃったりするのでためしにどうぞ。

ちなみに、WordPress以外でも同様の問題は起こりえるので、Nginxでゴチャゴチャしたりした方が楽かもしれません。

すべての投稿を見る

高橋文樹ニュースレター

高橋文樹が最近の活動報告、サイトでパブリックにできない情報などをお伝えするメーリングリストです。 滅多に送りませんので、ぜひご登録お願いいたします。 お得なダウンロードコンテンツなども計画中です。