徒労日記のhttps化 ~ Let’s Encryptの無料証明書でnginx上のwordpressを常時SSLに対応させる

LINEで送る
Pocket

正直やりたくないなぁ・・・と逃げていたらGoogle Chromeに真綿で首をくすぐられ続けていよいよ重い腰をあげたお話。

「サイトの安全性を高める」なんて崇高な目的よりも、個人Blogに至っては完全に「Google村八分が怖いから」。どうにも手段が目的化するパターンに陥っている気がしてなりません。

はじめに&レジュメ

よくある「https化とはなにか」や「SSL証明書とは」については他著名サイトに譲り、ここでは割愛します。

証明書の手配についてSSL証明書ならさくらのSSLあたりを使っておけばもっとスマートだったとは思うけれど、価値0円サイトにかかるコストはなるべく下げるべき。と思って無料のLet’s Encryptを利用させていただきました。種類としては一番カンタンなDV証明書(ドメイン認証型)となります。

構築環境は

  • Ubuntu 16.04.4 LTS
  • Python 2.7.12
  • nginx/1.10.3 (Ubuntu)

作業は大まかにいって以下手順をふみます。

  1. Let’s Encryptクライアント(certbot)のインストール
  2. SSL証明書の発行
  3. nginxとcronの変更
  4. WordPressへのSSL化プラグイン導入
  5. 動作テスト

今回の作業で参考にさせていただいた以下サイトには大変感謝しております。

Let’s Encryptクライアントのインストール

早速インストールからはじめます。

Let’s Encryptにはやり取りを自動化してくれるCertbotというクライアントがあるのでgitからとってきます

ここから特にどこかへインストールされたりしなかったため、後ほど/tmp/letsencryptから/usr/local/bin/letsencryptへ移動しました。

証明書の発行

ウィザード形式(?)でやってくれるスクリプトがついてくるので実行してみる。

Eメールアドレスやnewsletterに参加するかなど聞かれたあと・・・

はい失敗してるううう

UnicodeDecodeErrorとは?でググってみると、コミッタとおぼしき方のこんなコメントを発見。

Crash on starting certbot-nginx with a clean nginx install UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xc2 in position 10453: ordinal not in range(128) · Issue #5657 · certbot/certbot · GitHub


I think this is a duplicate of #5646 or one of the other Unicode issues mentioned there. This is definitely a bug in Certbot.

A likely workaround is to remove non-ASCII Unicode characters such as ö or ñ from comments and/or filenames in your nginx configuration file. In the future, Certbot should be fixed so it doesn’t crash when encountering these. Sorry for the inconvenience!

See also my comment related to this at

https://community.letsencrypt.org/t/certbot-unicodedecodeerror/52020/2

Certbotのバグだから、Unicode独自のasciiじゃない文字を消してみてね、ゴメン! との事。

Python3.5で実行してもダメ。更に調べると、Python自体のデフォルトエンコーディングをasciiからutf-8に変えてしまえばいいそうな。

これをutf-8に変える。

それにはpython*.*/site-packagesへsitecustomize.pyを置けばいい、と複数サイトに書いてあったのだけれど効果がなくてしばらくハマりました。
結局、findで見つけた/usr/lib/python2.7/sitecustomize.pyを書き換えたら動きました。

再実行。

動いた!
うまくいくと全部のhttpアクセスをhttpsにリダイレクトするか聞かれます。準備なしでは怖いのでいま時点は1: No redirectを選択。

今後はwebroot経由での証明書発行を行いたい為、単体での証明書発行もテスト。

エラーは無いけれど、「まだ新しいからスキップするね」と出ます。90日後がちょっと心配。

nginxとcronの設定変更

nginx

リダイレクトは拒否しましたが、証明書についてはcertbotのnginxプラグインがserverディレクティブへ勝手に追記してくれていました。

最後の5行が発行された証明書ファイルへのシンボリックリンク。
locationディレクティブは参照したサイトさんの真似。Let’s Encryptの定期更新プロセスがhttpsではなくhttpを利用するため、そこだけ例外するためのもの。

当初そのまま書いたら

と言われたためダブルクオーテーション(“)で囲んでいます。
301のhttpリダイレクトは後述のプラグインとバッティングしたため採用していません。

cron

定期的に証明書を更新する必要があるため、cronへジョブを追加します。nginxのリスタートも行うためrootのcrontabへ追記。

毎月1日の朝4時に再取得&リスタート。

WordPressをReally Simple SSLで一気に

転ばぬ先のバックアップ

何かする前にはフルバックアップ。

WordPressは設定画面とプラグイン

ちょっと緊張しながら管理画面の設定→一般にて「サイトアドレス (URL)」をhttps://してみました。
無事表示されて一安心。

問題は小ページやそれに対する既存のリンク。DB内文字列をすべて書き換える方法もありますが、今回は様子見もかねてReally Simple SSL | WordPress.orgを使いました。JavaScriptや内部処理を使って動的にリンクをhttps化してくれるそうです。

有効化するとこんな確認画面が表示されます。

「.cssでhttp://リンクがないか?」とか一瞬戸惑いましたが、目で確認すればいいやと思い切って有効化ボタンを押します。

結果、あっさりと全ページhttpsアクセスとなりました。「ワンクリックで SSL を有効化」の言葉に偽りなし。

参照しているサイト側も

自分を見ている側もわかる範囲で変えておきます。
思い当たるのはGoogle アナリティクスSearch Console

そもそもGoogleにSSL化を認識してもらいたいわけですから、抜かりなくいきましょう。

動作確認と見栄え

ちゃんと表示されるか複数のブラウザで確認しつつ、見え方がどう変わったのかチェックして行きます。

対応前

Chrome バージョン: 68.0.3440.84(Official Build) (64 ビット)。
アドレスバーの先頭にiマークがつき、保護されてない事を訴えます。おのれ。

Windows Edge。文章は柔らかいものの、同じ様な表示。

IE11は平常運転。

iOS版Chrome(今日時点の最新版)。こちらは特に警告表示が出ません。

Android版Chrome(今日時点の最新版)。端末のOSは6.0.1。情報のあるiマークだけが表示されます。

対応後

Chrome。緑のカギがつき「保護された通信」と表示されます。この表示が欲しかった!努力は報われました。

IEは見慣れた鍵マーク付きに。Windows10にインストールしたESETのフィルターも太鼓判。

IEはぱっと見変化がないものの、URL欄の末尾に鍵マークが付きます。

iOS版chromeも目立つ緑の鍵付きになりました。

Android版はiマークが消えて緑の鍵付きに。

おわりに

面倒くさい、お金かかるのいやだ、と逃げ回っていたSSL化が無事完了しました。粘った怪我の功名か、無料の証明書サービスが登場し簡単に利用できたのはラッキーです。支援団体や先人たちには感謝しきり。

SSLの安全性チェックではSSL Server Test (Powered by Qualys SSL Labs)にてA判定となりました。ひとまず安心してみなさんに提供できそうです。

2018/08/07 追記
トップページやカテゴリページは問題無いのに、個別記事のページだけ警告が出てしまう。プラグインが悪いのか?と思ったらh3見出しに使っているピンク色の鉛筆マーク。これの画像がstyle.css内でhttpで呼び出されていたのが原因でした。

やっぱりCSSでhttp://使ってましたよ!というオチ。
Chromeだと分かりづらかったけれど、Firefoxなら違反メッセージの中から詳細情報を呼び出し、リンク一つ一つのURIが確認できて調べやすかった。

コメントを残す