なんてことはない、ただRubyでHTTPSなWebサーバにアクセスしてGETでデータをとってくるというだけの話なんだけど...
問題発生
まず思いついたのがこのコード。
require 'net/https'
Net::HTTP.get(URI.parse("https://mcrn.jp/ret.cgi"))
しかし、次のようなエラーが返ってきてしまう。
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
from C:/Ruby21x/lib/ruby/2.1.0/net/http.rb:923:in `connect'
原因究明
もしかしてSNIに対応していない?と思ったけど違った(4年以上前に対応してる)。
さらに調べて、以下の記事をヒントに証明書の場所を調べてみてびっくり。
エラー:OpenSSL::SSL::SSLError SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed - komiyakの通り道
require 'openssl'
p OpenSSL::X509::DEFAULT_CERT_FILE
"C:/Users/Justin/Projects/knap-build/var/knapsack/software/x64-windows/openssl/1.0.1l/ssl/cert.pem"
=> "C:/Users/Justin/Projects/knap-build/var/knapsack/software/x64-windows/openssl/1.0.1l/ssl/cert.pem"
Justin!?誰???(※1)
ブログ移行に伴い、sblo.mcrn.jpをさくらのブログから外してリダイレクト用に設定しなおしたので、ついでに証明書を取ってSSL化。
これでmcrn.jp配下のドメインは全部SSL化できたので、.htaccessのHSTS設定にに「includeSubdomains」と「preload」を追加(※1)して、HSTS Preload Submissionに申請。
反映までにしばらくかかるけど、preloadじゃないHSTSは既に効いてる状態なので、.htaccessの強制HTTPSリダイレクトと組み合わせて完全HTTPSが実現。
時間がかかるかと思ってたURLマッチングが思いの外早く終わったので、だらだらと更新の止まったブログを晒してても意味がないし、さっさと移行してしまうことに。
流れとしては以下のような感じで、すでに3.まで済ませてあったので後は残りをするだけ。
- 「約定期blog GS」(以下、旧ブログ)の全データをバックアップ
- 「Luvelcrak」(以下、新ブログ)にデータをインポート(noindex、follow設定)
- カテゴリの調整など
- 旧ブログのURLとタイトルのペアを収集するスクレイピングツールをRubyで書いて実行
- 新ブログのURLとタイトルのペアを書き出すテンプレートをMTに登録して発行
- 4.と5.で作ったリストを付き合わせて、.htaccess用の「旧URL→新URL」リダイレクトリスト(Redirect permanent)を作る(216行)
- さくらのサーバ上に旧ブログドメイン用のフォルダを作って、6.のリストにトップページ用のRewriteRuleと404/403処理を追加した.htaccessを設置
- さくらのサーバ設定から「さくらのブログ」に割り当ててたサブドメインを7.で作ったフォルダに割り当て直す
- 新ブログのnoindex、followをはずして、旧ブログにnoindex、nofollowを付ける。
Movable Typeに移行&リニューアル予定のこのブログ。
移行計画はなかなか進んでないけど、それを良いことに新バージョンが出たのでさっそく適用。
今回はマイナーバージョンアップなので上書きでもよかったけど、念のためフルバージョンアップの手順で実行。
ついでにメモも作成。毎回公式手順探して確認するの面倒だし。
まあ、7.0とかになったらまた確認し直さないと行けないけど。
1.新しいMTのアーカイブ(zip)を取得
2.回答してtarに詰め直す
3.scpでアップロード
4.旧MTの実行ディレクトリをコピー
5.旧アーカイブ・スタティックのコピー
6.MT内から「ツール→バックアップ」
7.MySqlのバックアップ
mysqldump -u ユーザ名 -h ホスト名 -p db名 > バックアップファイル
8.3.でコピーした新MTを解凍
9.パーミッション修正
cd 新MTディレクトリ
find . -type f -print | xargs chmod 644
find . -type f -print | grep "\.cgi" | xargs chmod 755
find . -type f -print | grep "\.php" | xargs chmod 755
find . -type d -print | xargs chmod 755
※grepのバージョンはgrep (GNU grep) 2.5.1-FreeBSDだった。
10.旧MTをmvで別名にリネーム&新MTを旧MTにリネーム
mv mt/ mt60/
mv MT-6.2/ mt/
11.設定ファイルコピー
cp mt60/mt-config.cgi mt/
12.プラグインコピー
非対応・サポート終了などに注意。
※Loupeは使ってないし同梱されなくなったので移さなかった。
cp -a mt60/plugins/PostTweet/ mt/plugins/PostTweet/
13.サポートコピー
cp -a mt60/mt-static/support/ mt/mt-static/support/
14.テーマ
themes/以下に、追加したものがあれば。
今回は追加がなかったのでスキップ。
15.htaccess等
.htaccess、.htpasswdを使っていればそれもコピー
16.リビルドして確認
17.旧MTディレクトリをtarに詰めて退避&削除
mcrn.jpにgzip圧縮を導入。
.htaccessに
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html text/css text/javascript
と書くだけ。(参考:ブログやウェブサイトですぐに役立つ「.htaccess」の設定のまとめ | コリス)
さくらのレンタルサーバだとApacheは2.2.29が入ってるみたいだったので、最初2.1+のやり方を試したけどInternal Server Error。
仕方ないから旧方式でやったら成功。
でも、この「さくらのブログ」は対象外なんだよね…。
そもそもContent-TypeのcharsetがShift_JISだったりするし、やっぱりMT6に移行したい。
私も昔はShift_JIS原理主義(Shift_JISもといCP932以外に死を!!)だったけど、今はUTF-8穏健派(できればUTF-8使いたいけど、無理にとは言わない)。
2ドメイン目のSSL導入で「7 さくらのレンタルサーバでSSL通信を強制する | SSLそこからっすか!?」を見てたら、フォルダの切り方が
/home/ユーザー名/www/ <---> https://デフォルトドメイン/(変更不可)
/home/ユーザー名/www/ドメイン名A/ <---> https://ドメイン名A/
/home/ユーザー名/www/ドメイン名B/ <---> https://ドメイン名B/
みたいになってた。
…。
……。
………。
あーーーーーーーーー!そうすればよかったんだ!!
これなら.htaccessが他ドメインに影響することもないし、デフォルトドメイン(ユーザー名.sakura.ne.jp)はwww直下に.htaccess置いて(※)無効化できるし。
※:無効化のための最低限の設定(ホスト名判定でプライマリ独自ドメインへのリダイレクトor全アクセス拒否)だけ書くことで、他ドメインへの影響をなくす。
逆に全ドメインに影響させたい内容(「Header set X-UA-Compatible "IE=Edge"」等)を書いておく手も。
ということで、早速フォルダの移動・リネームを実施。
mcrn.jpとは別のドメインに2個目のラピッドSSLを導入。
今回はコントロールパネルから申し込んだので、さくら側で証明書設定までやってくれた。
…んだけど、途中でちょっとしたミスをしてしまい、手続き完了まで時間がかかってしまった。
ミス1.SNI SSLを有効にしてなかった
「6 さくらのレンタルサーバでSSLを導入する | SSLそこからっすか!?」によると、申し込んですぐにSNI SSLが有効にできるらしい。
前は自分でCSR送って、中間証明書入れて、証明書受け取ってセットして、それからONにしてたから気付かなかった。
ミス2.HSTSセットしてた
まだ証明書がないのに気が早すぎ。
ミス3.上位階層の.htaccessが誤って効いていた
これは別記事で詳しく。
将来的なHSTS導入に向けて、「www」サブドメインを廃止することにした。
…のはいいけど、単純にサーバコントロールパネルのドメイン設定で「wwwを付与せずマルチドメインとして使用する(上級者向け)」を選択するだけだと、ルート(http://www.example.com/)へのアクセスで「このサーバは、さくらのレンタルサーバで提供されています。」というデフォルトページ?が表示されてしまうし、httpsでのアクセスで証明書エラーが出てしまう。
理想としてはDNSエラーに落としたい。実際、wwwあり・なしのどちらかに統合してるサイトでも、こうやってるところは多い。とにかく、いくらなんでもさくらデフォルトページ表示は気持ち悪すぎる。
前にもwww廃止しようとして、結局このデフォルトページ問題に突き当たり、諦めて有効化&.htaccessリダイレクトで妥協したんだけど、今回、解決法が判明。
といっても、時間が無いので手短に。
HSTS:HTTP Strict Transport Security
HTTP Strict Transport Security (よく HSTS と略されます) は、Web サイトがブラウザに対して、HTTP の代わりに HTTPS を用いて通信を行うように伝達することができるセキュリティ機能です。(HTTP Strict Transport Security - Security | MDN)
とりあえず導入。
.htaccessに
Header set Strict-Transport-Security "max-age=315360000;"
って追加しておけば、対応するブラウザであればHTTPでアクセスしてもHTTPSになる。
さらにセキュリティを高めるためには、HSTS preload(ホワイトリストの先読み)があるんだけど、これをするにはサブドメイン含めて全てHTTPSにしないとだめ。
wwwはさくらのサーバコントロールパネルから無効にできる(でもhttps://www.mcrn.jp/(ルート)だけは404ではなくさくらのページが表示されてしまう)けど、問題はsblo。そう、ここ(2015/9/25時点)。
ということで、HSTS preload対応するためにはここは完全閉鎖しないとだめだけど、現時点の移行計画としてはしばらく残すつもりなので、HSTS preloadはかなり先かな。
まあ、移行計画自体前倒しで進んでる(というより勢いで突っ走ってる)から、予想より早いかもしれないけど。
新ブログに移行する作業をしていて、サイトグローバルの404ページではなく、ブログの404ページに飛ばすように/blog以下の.htaccessを書き換え。
そして、テストしてみると無事カスタムエラーが表示された…んだけど、ふと気になってChromeのデベロッパーツールで見てみると、何故か301リダイレクトが走って、エラーページ自体は200で表示されてる。
いわゆるソフト404。これはまずい。
でも、よくありがちな
ErrorDocument 404 https://foo.example.com/404.html
のように絶対URLを指定していなかったので、不思議に思い、mod_rewriteベース(REQUEST_FILE判定)や、CGIエラーページも試してみたけど、前者はそもそも全く反応せず、後者はエラーCGI自体こそ404を返すものの、一旦301でリダイレクトされてる。