本日このブログを常時SSL化したので、備忘録も兼ねてここに記しておく。
切り替えそのものはダッシュボードから簡単にできるのでまぁ簡単。
問題はその後。
まぁただ、以下の広野さんの記事を読んで、面倒な後処理が発生することは想定内ではあった。心の準備ができたので感謝!
www.mayoinu.com
目次
- SSLとは
- アドレスバー表示について
- 混在コンテンツについて
- はてなブログ全体のhttps化
- 個別の記事のhttps化
- Mixed-Contentsが存在する個別記事をスクリプトで探す方法
- 7/18追記
SSLとは
SSLとは、Secure Socket Layerの略で、暗号通信に使われる技術のことだ。
これをWebサイトの配信に用いたものがhttps。最後のエスがセキュアであることを示す。
これまでの常識では、単に情報を発信するページは暗号化されていないhttpで行い、訪問者にフォーム入力させるようなページ(とりわけクレジットカード番号や個人情報など)では、そのページだけSSLに対応したhttpsで通信するのがセオリーだった。
しかし米国NSAがhttpの性質を利用して、本来無害なサイトへのアクセスを改ざんしてスパイプログラムをインストールさせているという事実がエドワード・スノーデン氏により暴露され、以降は単に情報を発信するだけのサイトであっても全てのページをhttpsで通信させる方法(常時SSL)が常識化しつつある。
アドレスバー表示について
サイトがhttpsに対応して通信が暗号化されているとき、ブラウザのアドレスバーがそれぞれ次のように変化する。
Microsoft Edgeのアドレスバー表示
通信が保護されている場合
通信が保護されていない場合
このように、ブラウザによってどちらを明示的に表示させるかが違うので、SSL通信が上手くいってるかどうかは自分のブラウザのバージョンや仕様を確認したうえで判断が必要となる。
混在コンテンツについて
サイト本体がhttpsで暗号化されているとき、画像やCSSやJavascriptなど、ページのパーツとして同時に読み込まれる資源へのアクセスがhttpだと、保護されていない通信という扱いになってしまう。
これらの資源はページ本体をリクエストした際にサブリクエストで同時にダウンロードされるため、資源への通信がhttp通信だと折角ページ本体をhttpsで通信していても暗号化されていない通信が混じってしまう。
これを混在コンテンツ(Mixed-Contents)といい、ブラウザによっては通信が保護されていないと表示されてしまう(あるいは保護された通信と表示されない)。
単なる他ページへのリンクがhttpになっている分には問題ない。なぜならそれは資源ではないので、同時に読み込まれることはないから。
ただし常時SSL化の流れが加速すれば、将来ブラウザでHTTPサイトへのリンクをクリックした際に警告が表示されるなんてことになるだろうと私は予測している。
はてなブログ全体のhttps化
冒頭で述べたように、まずはダッシュボードの詳細設定で切り替えるだけ。ただし元のhttpには戻せないので注意。
それからデザインでサイドバー等に資源リンクがあればhttpをhttpsに書き換えるか、http:を消す必要がある。まぁ自分でカスタマイズした方であればそのあたりは大丈夫かと思う。HTMLタグだと単純にhttp:を消して//からアドレスを始めればサイトと同じ方式で通信してくれるので便利。※はてな記法でこの方法が使えないのが残念。
個別の記事のhttps化
これが一番大変。上手く行かないパターンは2つある。
保護されていない通信になるパターン
Amazon等のリンクや古い記事の画像等がうまくhttps化されてない。
ただ通常は画像やAmazonリンクの張替えまでは不要で、ページを編集して保存するだけで大抵の場合は直る。
編集といっても何も変更する必要はないのだが、それだと保存できないので、適当な場所に半角スペースでも入れて、更新ボタンが有効になったらスペースを消して更新すれば良い。
稀にAmazonリンクで古い商品を指してる場合はこれで治らないので最新の商品リンクを探してきて張り替える。
埋め込み資源が空白になるパターン
過去記事や他のブログを埋め込みリンクにしてる場合、資源としてサムネなどを取りに行くのでそこはhttpのままになっている。
Microsoft Edgeで試したところ、セキュリティ保護は問題なかったけど埋め込みコンテンツが取得できておらず真っ白。
つまり、http通信部分をカットしてるからセキュリティ保護が問題ないだけ。
自分の過去記事も含めて真っ白なので残念。
埋め込みコンテンツの中身をちゃんと表示させようと思ったら、httpsに書き換えていかないといけない。
Mixed-Contentsが存在する個別記事をスクリプトで探す方法
全ページ開いて。。なんてやってられない。
以下のサイトで良さげなスクリプトが紹介されているのでこれを活用させていだいた。
tech.innovation.co.jp
ただこのサイト、ソースコードが画像になっててとても残念。。
コピペできるようにこちらに引用再掲させていただく。
これをerror_scan.jsというファイル名でc:\workなど分かりやすいところに保存しておく。
※私の場合はe:\scriptに置いた。
//出典:https://tech.innovation.co.jp/2017/09/17/mixed-content-checker.html var system = require('system'); var url = system.args[1]; if (!/^https?:\/\//.test(url)) { console.log( 'URLを指定して下さい'); phantom.exit(); } var page = require('webpage').create(); page.onResourceRequested = function(request) { if (request.url.substr(0, 8) !== 'https://' && request.url.substr(0, 5) !== 'data:') { console.log('[mixed content]', request.url); } }; page.open(url, function(status) { phantom.exit(); });
次にこれを使うためにはPhantomJSというツールが必要。
PhantomJSを使うと、コマンドでWebコンテンツにアクセスできるようになるので、以下のサイトからまずこれを入手して任意のパスに解凍しておく。
http://phantomjs.org/download.html
PhantomJSのbinがあるフォルダを環境変数Pathに登録しておく。
次にコマンドプロンプトでerror_scan.jsを保存したフォルダに移動し、
「phantomjs error_scan.js チェックしたいURL」とコマンドを打つ。
上のように、mixed-contentsと表示されていたらHTTPS通信できてない資源があるということ。
問題ない時は何も表示されない。
次に、先ほど紹介したサイトにはPythonでSitemap.xmlを解読しつつ全ページスキャンするコードも書かれている。
こちらも画像なので、テキストで引用させていただく。
このスクリプトはchecker.pyというファイル名でerror_scan.jsと同じフォルダに入れておく。
# 出典:https://tech.innovation.co.jp/2017/09/17/mixed-content-checker.html import re import sys import ssl import subprocess import urllib.request from bs4 import BeautifulSoup def getMixedContentError(url): msg = "" result = subprocess.getoutput("phantomjs error_scan.js " + url) for line in result.split("\n"): if ("[mixed content]" in line): msg += line + "\n" return msg ssl._create_default_https_context = ssl._create_unverified_context sitemap_url = sys.argv[1] sitemap = urllib.request.urlopen(sitemap_url).read() soup = BeautifulSoup(sitemap) for url in soup.findAll("loc"): errorMessage = getMixedContentError(url.text) if (errorMessage): print("x " + url.text) print(errorMessage) else: print("v " + url.text)
Pythonのインストール方法はググっていただくとして、このスクリプトを使うにはbs4というライブラリをインストールする必要がある。
Python3.4以降に同梱されているpipというツールを使ってインストールするけど、Pythonをインストールしただけではpipにパスが通ってなかったので、環境変数にパスを追加しても良いけど、とりあえずpipのあるパスで実行することにした。
whereコマンドでPythonの場所を調べ、そこのScriptsフォルダに移動し、「pip install bs4」を実行。
実行するにはコマンドプロンプトでchecker.pyを保存したパスに移動し、
「python checker.py サイトマップのURL」を実行する。
はてなブログのサイトマップは「ブログURL/sitemap.xml」にある。
例えばこのブログなら、https://thom.hateblo.jp/sitemap.xml
そのxmlに更にページ番号がついたサイトマップが記載されており、実際にはこのページ番号付きのサイトマップをcheckr.pyに引き渡すことになる。
1ページ目はこんな感じ。
「python checker.py https://thom.hateblo.jp/sitemap.xml?page=1」
暫く待ってればpage1の中の全URLがチェックされるので、コマンド結果をコピペしてエディタに張り付ける。
先頭にvと付いたURLは問題なかったということ。
先頭にxと付いたURLは混在コンテンツなので要修正。
Mixed-Contentsと表示されているものはページ内で具体的にどれがhttp通信なのかを表示している。
余談だけど、EmEditor(エムエディタ)だと、リンククリックでそのままページを開けるので楽。
また一度開くと赤くマークされるので完了チェックリストとしても使える。
修正が終わったら、サイトマップの次のページのURLをchecker.pyに引き渡して実行する。
「python checker.py https://thom.hateblo.jp/sitemap.xml?page=2」
これの繰り返し。
ものすごく面倒くさかったけどまぁなんとか全ページSSL化完了した。
7/18追記
私は記事のMixed-Contentsの洗い出しまでをスクリプトでやったけれど、以下のブログ記事ではスクリプトによる記事の更新について書かれていて、更にスマートに作業できそう。
blog.jnito.com