WordPressを完全にSSLへ移行してみた

うちのサイトは証明書の関係で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をうけてみると・・・
Observatory 結果
うんA+でかなり良いスコアがでました。
 
設定、サーバー的には移行完了してもWordPressではまだ作業が残っちゃってるんです。

それは、WordPressのサイトURLの変更。
管理画面から設定⇒一般でURLのスキーム部分をhttpsへ変更するだけ。
WordPress: サイトURL変更

あと、Content Security Policy(CSP)なんかを設定しておくと、メディアライブラリーの画像が表示されないんです。
WordPress: メディアライブラリー URL修正前
これはCSPの設定でselfやhttpスキームを除いたドメインを設定していても発生します。
httpとhttpsサイトは別と判断されるんですねー。

なので画像のURLをhttpからhttpsに修正します。

<?php
 
if (is_admin() === true) {
    add_filter('wp_get_attachment_url', function($url) {
        return str_replace('http://', 'https://', $url);
    });
}
 
?>

これでメディアライブラリーが表示されるようになりましたー!
WordPress: メディアライブラリー URL修正後

これで管理画面の方はOK、次は既に公開済みの記事にある画像です。

記事の画像はHTMLで直接URLが指定されているので、WordPressの設定を変更するだけではダメ。
記事一つ一つ修正すれば良いんだろうけど、面倒なのでこんなコードを使ってURLをhttpsへ修正します。

<?php
 
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の敷居はかなり低くなっていい感じ。


トラックバックURL


スパム対策のためトラックバックURLを動的に生成しています。
生成されるトラックバックURLはコンテンツURLと紐付けされますので、コンテンツURLで指定したサイト以外では使用できませんのでご注意ください。
トラックバックの注意事項などの詳しい説明は About ページを閲覧してください。
「コンテンツURL」を入力し「URL生成」ボタンを押してください。
トラックバックを送る際はあなたの記事やコンテンツにこの記事のURLを書くかリンクしておいてください。
URLがない場合はスパムとして削除され以降の全トラックバックは拒否されます。

コメントを残す

メールアドレスは公開されません、また は必須項目です。
このブログに初めてコメントする方は こちら をご覧ください。


画像認証は待機中です、先にコメント本文を入力して下さい。

コメントを送信しています、しばらくお待ち下さい...
(Akismetスパムデータベース及びブラックリストへの照会を行っています)


キャンセルをした場合でもコメント投稿が完了している場合があります