GoogleがHTTPSに対応したサイトをランキングで優遇する方針を発表してから、Webサイトの常時SSL/TLS化がすごいスピードで進んでいるように感じられます。
今までは有料だったSSL/TLSは、今や let’s encrypt を筆頭に、CloudFlare や Amazon Certificate Managerなど、無料のSSL/TLS証明書を発行してくれるサービスが続出中。もはや常時SSL/TLS化が常識の時代です。
もっとも簡単かつおまけサービスもてんこ盛り(HTTP/2 やら 静的コンテンツのキャッシュやら)の CloudFlare を使ってサイトをHTTPSに対応してみました。
CloudFlare側の設定は最高に簡単なので、さらっと目を通しつつ、WordPressで使う時のポイントだけ紹介します。
ネームサーバーの変更
CloudFlareを使うためにはまず、利用しているレジストラ(お名前.comとかVALUE-DOMAINとか)の管理画面で、ネームサーバーをCloudFlare指定のネームサーバーに切り替える設定をする必要があります。
そうすると名前解決した時に、CloudFlareのプロキシサーバーを指すようになって、間で勝手にいろんな最適化してくれるというわけです。
最初にDNSレコードのスキャンが行われますが、DNSレコードをいじってない人にとっては基本的それで大丈夫だと思いますが、自分であれこれDNSレコードを追加したり変えたりしている人なら完全にスキャン結果を信用してはいけないです。なぜならスキャンされないレコードがあったり、あるはずもないレコードが出たりするので、自分の目で確認しておいたほうが良さそうです。
SSLのオプション
Cloudflareからサーバーへのリクエスト方は3タイプあります。
- Flexible
- Full
- Full (Strict)
Flexible
サーバー側でSSL/TLSを適用してない時にだけ使います。
CloudflareのSSLを利用しようと考えている人のほとんどがこの方式を使うことになります。ただ、ここに1つの落とし穴が。
下図が示すように、ユーザとCloudflareの間では確かにHTTPSで暗号化されていますが、Cloudflareとサーバーの間は通常のHTTP通信になります。つまりセキュアじゃないってことです。
ですから、Flexibleを使うのは「どうしてもサーバー側でSSL/TLSが使えない」時だけの最終手段にして下さい。
Full
ユーザとCloudflareの間はもちろん、サーバーとの間もちゃんとHTTPSで通信する方法。サーバー側で使っている証明書の有効性は問いません。オレオレ証明書でも構いません。オレオレ証明書でもいいから、サーバー側で証明書を設定できるならFlexibleより全然セキュアです。二重暗号化です。
Full (Strict)
Fullと同じく、ユーザとCloudflare、CloudflareとサーバーはHTTPS通信です。ただし、サーバー側で使う証明書は有効なものでなければいけないという点で違います。個人的にはサーバー側で有効な証明書が使えているならオフにしちゃったほうがいいかもです。二重暗号化するから多少なりともパフォーマンスに響きます。あっ、そもそもそれならこの記事読んでないのか(笑)
結論
サーバー側で証明書を設定できるならオレオレ証明書を発行して、「Full」を利用してもいいので、Flexibleを避けるべし!
WordPressの設定
WordPressの「設定」からURLをhttpsに変えます。
それか、wp-config.phpで以下の定数を定義しても同じことができます。
define('WP_HOME','https://example.com'); define('WP_SITEURL','https://example.com');
次に、データベースにあるURLもすべてhttpsに差し替えです。
WP-CLIが使える環境なら、
wp search-replace 'http://example.com' 'https://example.com'
の一発で終わります。
それが使えない環境なら、Search Regex(プラグイン)を使いましょう。
Flexibleを利用した時の設定
Flexible はよくないとは言え、何も暗号化されてないよりはましです。
WordPressをホストしていて、そして、どうしても「Flexible」を利用するしかないことになったとしましょう。
幾つか設定が必要になってきます。
無限リダイレクトループを絶つ
Flexibleの場合、Cloudflareとサーバーの間の通信がHTTPなのに、WordPressではHTTPSの設定にちゃっているから、WordPressはCloudflareからのリクエストをリダイレクトして、Cloudflareに戻り、そしてまたリダイレクト…
Cloudflare -> WordPress -> Cloudflare ...
の無限ループにハマってしまいます。wp-config.php
を開いて、以下を追加します。
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) { $_SERVER['HTTPS']='on'; }
HTTP を HTTPS にリダイレクトさせる
Apacheの場合
awsのelbと同じく、httpからのアクセスだと「X-Forwarded-Proto」ヘッダーの値がhttp
になるので、それを利用して、httpからのリクエストをhttpsにリダイレクトさせることが可能。
RewriteCond %{HTTP:X-Forwarded-Proto} =http RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Nginxの場合
Apacheの時のやり方と同じ原理です。
server { if ($http_x_forwarded_proto != https) { return 301 https://$host$request_uri; } }
感想
Cloudflare の Flexible SSL は便利ですが、セキュリティ的には不完全なので、はなるべく避けるようにしたほうがいいですよ!
個人的には let’s encrypt が使えるならそっちにシフトしたほうがいいと思います。
とはいえ、Cloudflare自体はいいので、他の便利な機能も山ほどあるし、ネームサーバーを変えるだけでできるから楽チンでいい感じです!