うちのサイトは証明書の関係でPreload HSTS(HTTP Strict Transport Security)にはしていないけれど、
HSTS設定前でもかなりhttpsからのアクセスがあったのでHSTSの設定をして、常にhttpsへ接続してもらうようにました。
で、2017年1月にリリース予定のChromium 56から、パスワードやカード情報を送信するhttpなサイトは「安全ではない」と表示するようになるようです。
Chromium Blog: Moving Towards a More Secure Web
HTTP/2.0になって完全にhttpは要らないんじゃ?って感じになってきてるみたいですね。
もうそれなら完全にSSLへ移行しちゃって良いんじゃないかー!って事で、httpをhttpsへ301でリダイレクトするようにしました。
方法はいろいろあるけれど、WordPressならrewriteで良いと思う。
RewriteEngine on RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://blog.wolfs.jp$1 [R=301,L]
ちなみに、RewriteRuleのURLで最後にスラッシュを入れるとリダイレクト先でダブルスラッシュになるので注意。
例:
RewriteRule: RewriteRule ^(.*)$ https://blog.wolfs.jp/$1 [R=301,L]
アクセスURL: http: //blog.wolfs.jp/page-1/
リダイレクトURL: https: //blog.wolfs.jp//page-1/
これの何が悪いかと言うと、
ダブルスラッシュになっているとWordPressのリダイレクトが働いてhttps://blog.wolfs.jp/page-1/へリダイレクトされるので合計2回リダイレクトされる事に。
かなり無駄なので注意。
RewriteBase /なんかを使うと良いけど、別にそんなの指定しなくても/を1つ抜くだけで動くから要らないとおもうw
この状態でMozillaが提供しているサイトのセキュリティ診断、Observatory by Mozillaをうけてみると・・・
うんA+でかなり良いスコアがでました。
設定、サーバー的には移行完了してもWordPressではまだ作業が残っちゃってるんです。
それは、WordPressのサイトURLの変更。
管理画面から設定⇒一般でURLのスキーム部分をhttpsへ変更するだけ。
あと、Content Security Policy(CSP)なんかを設定しておくと、メディアライブラリーの画像が表示されないんです。
これはCSPの設定でselfやhttpスキームを除いたドメインを設定していても発生します。
httpとhttpsサイトは別と判断されるんですねー。
なので画像のURLをhttpからhttpsに修正します。
if (is_admin() === true) { add_filter('wp_get_attachment_url', function($url) { return str_replace('http://', 'https://', $url); }); }
これで管理画面の方はOK、次は既に公開済みの記事にある画像です。
記事の画像はHTMLで直接URLが指定されているので、WordPressの設定を変更するだけではダメ。
記事一つ一つ修正すれば良いんだろうけど、面倒なのでこんなコードを使ってURLをhttpsへ修正します。
add_filter('the_content', function($content) { $content = preg_replace_callback('/<img(?P<prefix>.*?)src="(?P<url>[^"]*.)(?P<ext>bmp|gif|jpeg|jpg|png)"(?P<suffix>.*?)>/', function($m) { return '<img'.$m['prefix'].'src="'.replaceContentURL($m['url']).$m['ext'].'"'.$m['suffix'].'>'; }, $content); $content = preg_replace_callback('/<a(?P<prefix>.*?)href="(?P<url>[^"]*.)(?P<ext>bmp|gif|jpeg|jpg|png)"(?P<suffix>.*?)>/', function($m) { return '<a'.$m['prefix'].'href="'.replaceContentURL($m['url']).$m['ext'].'"'.$m['suffix'].'>'; }, $content); return $content; }, 90); add_filter('wp_calculate_image_srcset', function($srcset) { foreach ($srcset as $key => $value) { if (is_array($value) === true) { $srcset[$key]['url'] = replaceContentURL($srcset[$key]['url']); } } return $srcset; }, 90); function replaceContentURL($str) { return str_replace('http://', 'https://', $str); }
ちなみに、データベースの内容を直接変更すればこのコストはなくなるので、毎回毎回これが実行されるのがヤダ!って場合は、
_postsのguid、post_content
_postmetaのmeta_value
の内容を修正すれば問題なし。
_postmetaのmeta_valueはシリアライズされている場合があるので、SQLで置換してしまうとエラーになり値が初期化される場合があります。
なので、PHPでデコードして修正後の再度エンコードしてDBへ入れるのが安全です。
これで完全にSSLへ移行することが出来たと思います。
今は個人でも無料でSSL証明書を発行してくれるサービスもありますし、SSLの敷居はかなり低くなっていい感じ。
コメント
コメントフォームへ