情報科学屋さんを目指す人のメモ

方法・手順・解説を書き残すブログ。私と同じことを繰り返さずに済むように。

Cloudflare+リバースプロキシ(Nginx)+WordPressのHTTPS化(常時SSL化、Let’s Encrypt利用)手順・設定変更・調査メモ

Apache (8) CloudFlare (9) HTTPS (3) Nginx (15) Ubuntu (27) WordPress (80)

今月、このサイトの常時SSL化(HTTPS化)を行いました。このサイト自体はWordPressで動作していますが、一番手前にはCDNとしてCloudflare、次にリバースプロキシとしてNginx、そしてその裏に実際にWordPressが動作しているウェブサーバーApacheがある、という多段構成であるため、移行の前に調べることが多くなり厄介でした。

今回実際にHTTPS化を進めてみた手順及び、その過程で分かったことや事前に調べたことなどをまとめておきます。

目次

手順のポイント:ゆるやかに移行する

ひとつ大きなポイントは、一気に完璧なHTTPS移行をしようとするのではなく、段階を踏んで、様子を見ながら進めることです。例えば「できるだけいざという時にHTTPに戻せる状態を保ちながら作業を進めること」や「少しずつ変えていくこと」「強力な設定変更を後回しにすること」が大切となります。

Googleは、HTTPS移行の際に、いきなり短期間に完璧な状態を目指して移行するのではなく、順を追って、時間をかけて移行するように推奨しています。例えば「HSTS」の設定は、より良い常時SSLの設定としてよく紹介されます(Googleも紹介している)が、こちらは一度設定してしまうとユーザー側のブラウザに保存され、証明書の期限切れなどのトラブルが発生した際にかなり致命的な状態になってしまいます。そのため、証明書の運用が軌道に乗るまで有効化しないように、などと推奨されていたりします。

注: サイトを既知の HSTS ホストとして認識しているクライアントは、多くの場合、サイトに期限切れの証明書などの TLS 設定のエラーが一度でもあるとハードフェイルします。HSTS の明示的な設計上、ネットワーク攻撃者が、HTTPS なしでサイトにアクセスするようクライアントを仕向けることができないようにします。証明書の検証エラーのまま HTTPS を展開することがないよう、サイトの運営が十分に堅牢であることを確認するまで、HSTS を有効にしないでください。 引用元

今回の前提:サーバーの構成

そこまで複雑ではないのですが、大前提となるサーバー側の構成を紹介しておきます。

まずユーザーのウェブブラウザは、Cloudflareのサーバーにアクセスします。すると、その裏側にあるオリジンサーバーに実際のコンテンツを探しに行くのですが、そこで待ち受けるのは、リバースプロキシのNginxです。そしてNginxも、その裏側にあるApacheサーバーにリクエストを飛ばし、WordPressが動作して、実際のコンテンツを取得して、そのコンテンツが今の経路を逆走し、ユーザーに届く、そんな流れです。

つまり、「ブラウザ」→「Cloudflare」→「Nginx」→「Apache(WordPressはここ)」のようにリクエストが転送されていきます

「HTTPS化」すべき場所

ウェブサイトを常時SSL化する今回の直近の目的は、ユーザーが利用するChromeブラウザ上に「保護されていません」と表示されないようにすることです。

この場合、HTTPS化すべきなのは、「ブラウザ」→「Cloudflare」の部分という、ブラウザと直接通信を行う最前面部分となります。

その裏側がどのようになっていようと、ひとまずそのサイトは「HTTPS化された」ということになります(WordPressが返すページ自体もうまくHTTPS対応版になっていないと「保護された通信」になれない不完全なHTTPS対応になってしまうので、WordPress側の対応文字大事)。

するとまず調査すべきは「Cloudflare」のHTTPS化です。

デフォルトで実はHTTPSを受け付けているCloudflare

しかし実は、Cloudflareを導入した時点で、HTTPS化はされています。

というのも、Cloudflareは、何もしなくてもはじめから各登録ウェブサイト向けの証明書を代理で作成しておいてくれていて、Cloudflare上に配備し、HTTPSリクエストを受け付けてくれているのです

なので、何も準備せずに「https://did2memo.net/」にアクセスするだけで、HTTPS通信はバッチリでした。

裏側がHTTPSを受け付けている必要あり

ただし、そのアクセス結果がこちら:

この通り、「Error 521 Web server is down」というエラーになってしまいます。確かにこのとき、「ブラウザ」から「Cloudflare」までのところはHTTPS化されているのですが、肝心のページの内容を取得することができていません

これは、Cloudflareが、裏側のサーバー(Nginx)に対して「HTTPS」で要求を転送しているものの、そのNginx側が「HTTPS」の要求に回答できなかったことが原因です。

つまり結局の所、裏側もHTTPS対応してはじめて、HTTPS対応かつ正常にページが表示できるようになるというわけです。

ただ、実はこの「裏側もHTTPS対応してはじめて」という部分にはいくつかの選択肢があります。

CloudflareのHTTPS対応には3つの種類がある

ブラウザとCloudflareとの間がHTTPS通信するのは当然として、Cloudflareとその裏側のサーバー(Nginx)がどう通信するかについては、Cloudflareが3つの設定を用意しています。

それが「Crypto>SSL」設定の3つの選択肢「Flexible SSL」「Full SSL」「Full SSL (strict)」です(設定自体にはもう一つ「Off」があり、そちらを選択すると、Cloudflareの時点で完全にHTTPS通信を受け付けなくなります)

「Full SSL」がデフォルトで、こちらは先ほど紹介した通り、裏側のサーバー(Nginx)がHTTPS要求を受け付けなければなりません

「Flexible SSL」は、裏側のサーバー(Nginx)に対して、HTTPで要求を飛ばします。「何それすごい、それなら対応簡単じゃん」と思うかもしれないのですが、それはそれでいくつか問題があり、リダイレクトループ問題や、いざ何らかの理由でCloudflareの利用を止めたいときに、Cloudflareを外してしまうと、HTTPSを受け付けることができなくなってしまう問題もあります。そこで今回はFlexible SSLは却下しました(他にも色々問題があり、裏側でHTTPS対応できない場合の最終手段として使うのがお勧め)。

「Flexible SSL (strict)」は逆により厳しい設定で、裏側のサーバー(Nginx)がHTTPS要求を受け付けつつ、そのHTTPS通信に利用される証明書が、有効期限内かつちゃんと信頼された認証局によって署名されている必要があります

この「Flexible SSL (strict)」を選択するとより厳密な運用ができるのですが、今回はわざわざこちらを選ばず、デフォルトの「Flexible SSL」を利用することとしました。

すると裏側はもうどんな証明書を使おうが一応動く、ということにはなるのですが、やはりそれではCloudflareに頼りすぎなので、今回は裏側のサーバー(Nginx)でHTTPS対応を行う際、ちゃんと有効な証明書を用意していきます。

Cloudflareが使う証明書にも選択肢がある

Cloudflareの話を離れる前に、もう一つCloudflareにはSSLに関する重要な設定があります。それはCloudflareが利用する証明書のタイプです。

「はじめからCloudflareが証明書を用意してくれている」と紹介しましたが、それはCloudflareが用意した、「複数のユーザー(ウェブサイト)が共通で使う証明書」です(「Universal SSL (Shared)」プラン)

この証明書は、証明書の対象ドメインに、自分のドメイン以外にも多数の知らないドメインが同居しています。信頼感かなり低めですが、この証明書は無料で利用可能です。

一方で、「Order SSL Certificate」という選択肢があって、専用の証明書をCloudflareに用意してもらえるサービスがあります。自分のドメインと、そのサブドメインのワイルドカードしか対象にしない、専用の証明書を利用できる「Dedicated SSL Certificate」プラン(月額5ドル)と、さらに複数のドメインをそこに50件まで追加できる「Dedicated SSL Certificate with Custome Hostnames」(月額10ドル)があります。

そしてさらに別の方法として、既に持っている証明書や、別のところで発行した証明書、ドメイン認証以外の証明書(EV証明書)などを使いたいといった場合は、持ち込み証明書を使える「Upload Custom SSL Certificate」という仕組みがあります。ただしこちらはCloudflare自体の契約を「Business」プランか「Enterprise」プランにする必要があり、最低月額200ドルが必要となります。この目的だけで選択するにはかなり高価なプランとなってしまいます。

ただ証明書を預ける形となるため、静的コンテンツ・大容量コンテンツのみCloudflareにホストしてもらって専用の証明書を使い、メインのページ自体は別の本気の証明書を使うなどのケアも検討した方が良いかも知れません。

とはいえ今回の目的的にはCloudflareの最もベーシックな証明書でよいため、特に今回は証明書の追加購入やプラン変更は行いませんでした

移行手順のポイント

となると実は、Cloudflare側で今すぐ行うべき設定変更はなく、まず注力すべきは、Nginxより裏側の、「Nginx→Apache(WordPress)」の範囲のHTTPS化対応です

ここで大切なのは、「いつでもHTTPに戻せるように、様子をうかがいつつ、ゆるやかに移行する」ことです。このような進め方をGoogleも推奨しています。

そしてその際まず大きな影響なく進められる作業が、WordPressのテーマ(テンプレート)を、HTTPS/HTTP両対応にする作業です。ここでのポイントはつまり、現在の「HTTP専用(HTTPのことしか考えていない状態)」から「HTTPS専用」にするのではなく、「HTTPからのアクセスが来たらHTTP版を返し、HTTPSからのアクセスが来たらHTTPS版を返す」ようにWordPressを構成する点です。

WordPressテーマをHTTP/HTTPS両対応にする

WordPressテーマをHTTP/HTTPS両対応にする際のキーワードは、「プロトコル相対」と「HTTP/HTTPS両対応になるようなテーマの書き方(WordPress関数の使い方)」です。

「行儀の悪くないプラグイン」や、WordPress本体が行うヘッダ挿入(事前に登録されたJavaScriptの読み込みコードなど)は、多くの場合自動的にHTTP/HTTPSを振り分けてくれるため、「WordPressテーマ」内の対応が中心となります(細かいところは実際にHTTPSで動かしながら検証するのが良いのですが、今から紹介する「明らかに未対応」な部分をまず先回り対応しておくのことがおすすめです)。

プロトコル相対化

こちらは単純で、WordPressテーマ内に登場する別のファイルを読み込んで表示する系(画像やCSSなど)の記述に出現する「src="http://..."」のようなURLの記述を「src="//..."」のように、「http://...」とも「https://...」とも書かずに「//...」とだけ書く、という方法です。

こうすることで、ウェブページが「http」の場合は「http」で、「https」の場合は「https」でファイルを取得するようになります。こちらをWordPressテーマを見ながら、順番に対応していきます。

HTTP/HTTPS両対応になるようなテーマの書き方(WordPress関数の使い方)

WordPressテーマには、URLが直接書かれていなくても、関数を実行した結果URLが生成される場所が多数あるはずです

そのうちの多くでは、is_ssl関数のおかげで自動的にHTTP/HTTPSが振り分けられるのですが、代表的な振り分けが行われない例があります。

それが「bloginfo('url')」のような記述です。こちらは、一般設定で指定したウェブサイトのURLがそのまま挿入される書き方なので、ちゃんとHTTP/HTTPSが振り分けられる新しい書き方「home_url('/')」に置き換える必要があります。

実際にはトップページであれば「“?php echo esc_url( home_url( '/' ) ); ?”」のように書くと、これがHTTPアクセス時には「http://did2memo.net/」に、HTTPSアクセス時には「https://did2memo.net/」と展開されてくれます。

また、home_url( '/feed/' )のように書き換えると、「http(s)://did2memo.net/feed/」のようにそのパスを含めたURLを展開してくれます。もちろん「“?php echo esc_url( home_url( '/' ) . 'feed/'); ?”」のように、外側で追加する方法も可能です。ただ、home_url('/')を使った時点で末尾に「/」が付くので、この点は注意してください。

補足:rel=canonicalはプロトコルを固定するのが理想

なお、rel=canonicalは、プロトコルを固定して記載した方が良く、http/httpsどちらからのアクセスに対しても、http側がメインなのか、https側がメインなのかのどちらかを、統一してり示しておきたい特別な場所です。

つまり今回は、移行作業がある程度完了して切り替えることにするまで「rel=canonical」のURLは「http」固定にしておきます。最終的に、「https」固定にします。

この書き方は別記事で。

「Let's Encrypt」を使って無料のセキュリティ証明書を取得する

WordPressテンプレートの準備があらかたできたら、実際にHTTPSでアクセスして動作を見ながら最後のほうを詰めたいのですが、HTTPSでアクセスするにあたって今回は「Let's Encrypt」というサービスを利用して、無料の証明書を取得することにしました。

Let's Encryptでは、支払いはもちろんのこと、個人情報の入力などの事務的な手続きもなく、Let's Encryptが用意しているツール(Certbot)のコマンドを実行していくだけで自動的にドメインの所有者確認が行われて、証明書ファイルを取得することができます。

一番シンプルなウェブサーバーが単一で動作している場合、そのLet's Encryptのコマンドがウェブサーバー上に特定のファイルを設置し、Let's Encrypt側が外部からそのファイルにアクセスできるかどうかを確認して、ドメインの所有者確認を行います。

しかし今回はCloudflareの裏側であることなどいくつかの理由から、そのウェブサーバー上に設置したファイルを確認してもらう認証方法(tls-sni-01方式)ではなく、DNSレコードに設置した専用の情報を確認してもらう認証方法(dns-01方式)を利用することにしました。

またDNSレコードの書き換えは結局はCloudflareの設定で行うことができるので、Cloudflare APIを利用して自動でDNSの設定を書き換えて認証を行ってくれるCertbot用のCloudflareプラグインを利用することにしました。

Certbot + Cloudflareプラグインのインストール

まず「$ sudo apt-get update」「$ sudo apt-cache search letsencrypt」でパッケージを確認してみたのですが、Cloudflareプラグインのインストールまでは無理そうでした(Ubuntu 16.04 LTS 環境)。また、「$ sudo apt-get install software-properties-common」「$ sudo add-apt-repository ppa:certbot/certbot」「$ sudo apt-get update」「$ sudo apt-cache search certbot」としてみましたが、やはりCloudflareプラグインは別途用意する必要があるようで、今回はCertbotの取得方法含めて別の方法を利用することにしました。

そこで、以下の手順でインストールを行いました:

$ sudo apt-get install libssl-dev
$ sudo apt-get install python3-pip
$ sudo pip3 install certbot
$ sertbot --version
certbot 0.26.1
$ pip3 install certbot-dns-cloudflare

これで、CertbotとそのCloudflareプラグインの導入が完了しました。

Cloudflareプラグインの設定ファイルを作成する

次に、Cloudflare APIに利用するアカウント情報(メールアドレス+API Key)を調べて、その情報をCloudflareプラグイン用のiniファイルにしてあげます(API実行自体はプラグインが実施するため、Cloudflare APIの使い方を学習する必要はありません)。

まずCloudflareのアカウントページにアクセスして、「Global API Key」の「View」から、「API Key」を調べます:

そうしたら、Viewを押して表示された「API Key」を元に、以下のようなファイルを作成します(メールアドレスは、Cloudflareに登録しているメールアドレス):

dns_cloudflare_email = cloudflare@example.com
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234567

このとき、「$ chmod 600 /path/to/cloudflare-credentials.ini」でパーミッションを変更しておきます。

Certbotを使って証明書を発行する

iniファイルの準備ができたら、次のコマンドを実行します:

$ sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /path/to/cloudflare-credentials.ini  -d your.domain.example.com

すると実行結果が次のように表示されて、生成された証明書ファイルと秘密鍵ファイルが「/etc/aletsencrypt/live/did2memo.net/fullchain.pem」と「/etc/(letsencrypt/live/did2memo.net/privkey.pem」に生成された(実際はシンボリックリンク)ことがわかります:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-cloudflare, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): ○○○○@gmail.com

Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom.
(Y)es/(N)o: N
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for did2memo.net
Waiting 10 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and schain htve been saved at:
   /etc/aletsencrypt/live/did2memo.net/fullchain.pem
 - Your-key-file has been-saved-at:
   /etc/(letsencrypt/live/did2memo.net/privkey.pem
   Your cert will expire on 2018-10-18. To obtain a new or tweaked
-  version of this certificate in the future, simply run certbot
   again. bTownon-ngteractively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   confinguration directory atc/etc/let,encrypt. You should make a
   secure-backup of-this folder-now. This-configuration-directory-will
   also contain certificates and private keys obtained by Certbot so
   makning regular backups of this folder is ideal.
 - If you likhe Certbot, please consider supporting our work by:
   Doinating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Doinating to EFF:                    https://eff.org/donate-le

NginxにHTTPSを受け付けるようにする

こうしてあっさりと「fullchain.pem」と「privkey.pem」を入手できたので、nginxの設定ファイル(/etc/nginx/conf.d/default.confなど)を書き換えて、HTTPS(443)でのアクセスを受け付けるようにします

HTTPS対応をする場合、既存のserverブロック(server{})に加えて新たにHTTPS設定用のserverブロックを追加しても良いのですが、あくまで「移行」であって別サーバーを立てたいわけではないので、もともと「listen 80 default_server;」のように書かれているserverブロック内に、追加で以下を追記しました(パスは、先ほどのcertbotコマンドの実行結果を書き写す):

listen 443 ssl default_server;
ssl_certificate /etc/letsencrypt/live/did2memo.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/did2memo.net/privkey.pem;

「$ sudo nginx -t」で設定ファイルの静的チェックをして「$ sudo systemctl restart nginx.service」で再起動を行いました。

すると、HTTPS経由でのWordPressへのアクセスができるようになりました

HTTPS化したWordPressの表示が大きく崩れた原因と対策

しかし、WordPressの表示は大崩壊してしまいました

これは何故かというと、Mixed Contentsと呼ばれる状態になってしまっていたことが原因です。

というのもここまでの設定では、NginxはHTTPSを受け付けます。しかし、Nginxは、WordPressが動作するApacheに対してHTTPSではなくHTTPでページの情報をリクエストします。

するとApache上で動くWordPressとしては、いつも通りHTTP用の内容を返すこととなります。

その結果を表示するブラウザ側としては、「HTTPS」でアクセスしたページ内に「HTTP」でCSSやJavaScriptファイルが参照されていることが分かり(これがMixed Contents状態)、それらのファイルへのアクセスをブロックしてしまうのです(ブロックを解除すれば見れる、という状態。ただ、ユーザー側が毎回アクセスごとに解除する必要がある)。

序盤で、WordPressに「https/http両対応」を行いました。それが機能するためには、「NginxからApache」のところもHTTPS化しなければならないのでしょうか。

実はこれには特別な対処法が存在します。そちらを利用すれば、わざわざApacheにまでHTTPS対応する必要はありません。HTTPS用のページがリクエストされていることをWordPressに伝える対応を行えば十分です。

WordPressにHTTPS用のページをリクエストする(Nginxの設定を変更して「X-Forwarded-Proto」ヘッダを追加する)

そのためにNginxの設定ファイルをさらに変更して、「HTTPS用のページを返してください」と伝えるための「X-Forwarded-Proto: https」ヘッダを追加します。

まずnginxの設定ファイル側(serverブロックのすぐ外側)に以下を追加して、httpでアクセスしたときはhttp、httpsでアクセスしたときはhttpsが入る「$thescheme」変数を作ります:

map $http_x_forwarded_proto $thescheme {
    default $scheme;
    https https;
}

そしてserverブロックの中にあるlocationブロックでその「$thescheme」変数を「X-Forwarded-Proto」ヘッダに設定し、設定後Nginxを再起動します:

proxy_set_header X-Forwarded-Proto $thescheme;

WordPress側の設定を書き換える

次に、このヘッダ情報を読み取って、WordPressがHTTPSからのアクセスかどうかを判定するのに利用している「$_SERVER['HTTPS']」を「on」に設定するため、「wp-config.php」に、次のコードを挿入しました

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
    $_SERVER['HTTPS'] = 'on';

この設定を終えてから再度HTTPSでアクセスすると、大幅な表示崩れは解消されました。

WordPressのテンプレート・プラグインの微修正

しかし部分的なMixed Contentsが残っていたので、「Open Graph Pro」プラグインで生成していたサムネイル画像のURLをプロトコル相対に変更したり、「Adjustly Collapse」がプラグインのリソースのパスを指定しているソースを修正するなどして、記事の本文に含まれる画像など、記事ごとに異なる部分以外の対応を済ませました

記事に含まれる「http」の読み込みを「https」に置き換える

ここまででテンプレートやプラグインなど、ページをまたいで共通で使われるHTMLについては、HTTPSでアクセスすればHTTPS向けのコンテンツが返ってくるようになりました。

ちなみに、HTTPでアクセスした際にHTTPSのリソース(CSSやJavaScript、画像など)を読み込む分には問題ないのですが、HTTPS接続に問題が発生したときにHTTPに戻せるように、という意味合いもあるので、テンプレートは完全な両対応をしておきました。

いよいよ残るは記事本文中で使われている「imgタグの画像埋め込み」や「aタグのサイト内リンク(※こちらは対策必須ではないのですが、リダイレクトコストの削減と、記事本文内をhttpsに統一するために、まとめて対応しておきます)」で使われている「http」の「https」化です。

現時点では、Consoleには次の「Mixed Content」エラー(警告)が表示され、アドレスバーにも「保護された通信」とも表示されません。このMixed Contentの警告を解消しない限り、例えHTTPSでのアクセスを提供していたとしてもそれは不完全であるとみなされて、「保護された通信」として扱ってくれません。

Mixed Content: The page at '...' was loaded over HTTPS, but requested an insecure image '...'. This content should also be served over HTTPS.

本文内のhttpをhttps対応するにあたって「このコンテンツ部分もプロトコル相対にすればよいのでは?」と迷うところなのですが、WordPress本体のエディタが画像を埋め込むコードを生成するときに「http」か「https」かのプロトコルを明示的に埋め込んでしまうため、ここは「両対応(プロトコル相対)」ではなく、「https」に統一することにしました(※内部リンクも書き換えるため、この段階で万が一何らかの原因でhttpsが失敗するようになった場合、画像が消えるだけ、とはいきません。そうなったら再置換して戻す覚悟で)。

そこでここから、記事本文内の自ドメインURLについて、「http」から「https」へ一斉置換を行います。

バックアップ

ここからは大規模なデータベース書き換えとなるので、まず最初にデータのバックアップを行いました。

プラグイン選定

置換するにあたってMySQLを直接操作する方法もあるのですが、今回はより手軽に置換するため、WordPressプラグインを使うことにしました。

最初に試したのは「Search Regex」プラグインでしたが、書き換えるデータベースの量が多すぎるためか、最初に100件試したときは動作したのですが、全記事の一括置換を実施してみると、結果画面が表示されず、真っ白な画面のまま固まってしまいました。

次に「CM On Demand Search And Replace」プラグインを試してみました。こちらはうまく動作したのですが、このプラグインはDB書き換えを行うのではなく、本文を表示する際のフックとして置換動作するプラグインのため、プラグインの動作に強く依存してしまうため、利用を見送りました。

「Better Search Replace」プラグインで一斉置換

そこで最終的に利用したのが「Better Search Replace」というプラグインです。

プラグインをインストールして、「Beter Search Replace」の「Search/Replace」タブを開いたら、「Search for」に「="http://did2memo.net/"」、「Replace with"」に「="https://did2memo.net/"」を指定して「img src="http://did2memo.net/wp-content..."」や「a href="...」の置換を行うようにします。また「Better Search Replace」プラグインでは「Select tables」設定で、置換を行うMySQLのテーブルを指定できる(しなければならない)ので、そこでは「posts」テーブルを指定しました(実際にはprefixが付いているので「******posts」のような名前)。

そして「Run Search/Replace」をクリックして一度実行してみたところ「An error occurred processing your request. Try decreasing the "Max Page Size", or contact support.」と表示されてしまったので、一度「Settings」タブで「Max Page Size」を「5000」に設定して再度実行しました。

すると今度は「DRY RUN(予行練習のような実行のこと。実際には実施されず、どのような結果が起こるかをテストできる仕組み)」が実施され、「DRY RUN: 1 tables were searched, ***** cells were found that need to be updated, and 0 changes were made. Click here for more details, or use the form below to run the search/replace.」という成功通知が表示されました。

そこで「Run as dry run?」の「If checked, no changes will be made to the database, allowing you to check the results beforehand.」のチェックを外してもう一度実行しました。

しばらく待つと「During the search/replace, 1 tables were searched, with ***** cells changed in ***** updates. Click here for more details.」と成功表示が出て、記事本文中の「http」だった内部リンク・リソース参照が「https」化されました

これにより、一気にMixed Contentが解消されました。

HTTPSでアクセスしてくれれば、ちゃんと「保護された通信」として表示される状態に

ここまでで、ひとまず「HTTPS」のURLでアクセスしてくれれば、「保護された通信」として表示される状態になりました。

しかし現状は「HTTP」側が標準です。ここから「HTTPS」側を標準に切り替えていきます

link rel=canonicalで「HTTPS」サイトを指定する

まず最初に、表面的な挙動は変わらない(引き続きHTTPサイトを利用できる)ものの、Googleを初めとする検索エンジンなどに対して「HTTPS側が正です」と伝えるために、「HTTP」に固定していたlink rel=canonicalの指定URLを、「HTTPS」に固定します。

// 強制的にrel="canonical"をhttps固定にする
remove_action ( 'wp_head' , 'rel_canonical' ) ;
add_action ( 'wp_head' , 'my_rel_canonical', 9 ) ;

function my_rel_canonical () {
	if ( is_home() || is_front_page() ) {
		echo "\n" . '<link rel="canonical" href="' . esc_url( home_url( '/' , 'https' ) ) . '" />' . "\n";
	} else {
		ob_start();
		rel_canonical();
		$rel_content = ob_get_contents();
		ob_end_clean();
		echo "\n" . str_replace ( "http:" , "https:" , $rel_content );
	}
}

こうすることで、「HTTP」にアクセスしたクローラは「HTTPSのサイトがあって、そっちが標準らしいぞ」と気が付くことになります。

HTTP→HTTPSリダイレクトを設定する

次に、HTTPのページにアクセスされた際に、HTTPSのページにリダイレクト(301リダイレクト)する設定を行います。

こうすることで、従来通りHTTPでアクセスしようとしても、自動的にHTTPSが開くようになり、HTTPSのページを閲覧するように強制することとなります。

通常この設定はNginxなりApacheなりウェブサーバー側で、.htaccessなどを使って行うのですが、実はCloudflareには、Cloudflare(のエッジサーバー)の時点で301リダイレクトを行うための設定が用意されています。こちらのほうがオーバーヘッドも小さいため、今回はそのCloudflareの設定を利用することにしました。

Cloudflareの設定の「Crypto」タブにある「Always use HTTPS」を「On」に切り替えます。これだけで一斉にhttpへのアクセスに対して、httpsのURLへの301リダイレクトが有効化されました。

これでhttpにアクセスすると強制的にhttpsへ転送され、サイトの閲覧にHTTPは利用できなくなります。

またこのとき、一度HTTPSに転送してしまえば、それ以降の内部リンクはすべてHTTPS化済みなので、内部リンクをたどる際はリダイレクトのオーバーヘッドの影響を受けません。また、リソース(画像やCSS/JavaScriptなど)を読み込む際も同様です。

管理画面のHTTPS化

実はここまでで、WordPressの管理画面(記事を書く画面など)も301リダイレクトの影響で強制的にHTTPS化されます。しかし管理画面ではテンプレートとは異なり、引き続き「http」でアクセスしてしまうカ所が発生します(記事編集画面に表示されるサムネイル画像など)。

この対策にもなる重要な設定として、WordPressの「設定>一般」にある「WordPressアドレス(URL)」および「サイトアドレス(URL)」に入力されているURLもhttps化して、設定を保存します。

サイトマップの変更

元々「https://~/sitemap.xml.gz」にアクセスすればhttps版のサイトマップを取得できる状態で、この後Google Search Consoleでそのサイトマップを指定すればGoogleに対して正しいサイトマップを伝えること自体は可能なのですが、実は「robots.txt」に「Sitemap:http://~/sitemap.xml.gz」という記述がありました。そこでこちらも「https」へと変更しておきました。

サイトのHTTPS化から外部サイトの設定変更へ

ここまでの作業で、ほぼ基本的なHTTPS化作業は完了しました。

ここからは、サイトそのものではなく、Google Search Consoleなど、外部サイトへの登録情報変更などを行っていきます。

Google Search Consoleへの設定

Google Search Consoleでは、「https」用のサイトを新規登録する必要があります。

Search Consoleのホーム画面右上にある「プロパティを追加」から、HTTPSのサイトを新規追加しました。

また同時に「www」版のサイトも追加して、「www」がないほうのURLを標準に設定しました。

Google Analyticsの設定

Google Analyticsは、既にあるプロパティとビューの設定をhttpsに切り替えるだけでOKです。

設定を開いて「プロパティ>プロパティ設定」と「ビュー>ビューの設定」それぞれにある「サイトのURL」をhttp://からhttps://に切り替えて設定完了です。

第一段階完了

ここまででひとまず「保護された通信」として表示され、基本的な設定変更は完了しました。

冒頭紹介したようなHSTSなど、まだ行っていない設定項目が色々あるのですが、そちらは様子を見ながら順番に変更していく予定です。

その他の参考

コメント(0)

新しいコメントを投稿