最近、 Google Chrome を中心とした、 SSL/TLS証明書に関するニュースが目立つようになりました。最近の案件でも、 HTTPS への移行を担当していたりします。
時代は、 HTTPS を求めていますね。 HTTP のみを使ってるウェブサイトのオーナーは、 HTTPS への移行が課題となってきています。
実は、 HTTPS に変えるだけでは不十分で、 SSL/TLS は攻撃手法がいくつか見つかっています。 HTTPS で立ち上げたサイトをより安全にするためには、対応すべきところがいくつかあります。セキュリティに関する課題ですね。
今回はそれを説明していこうと思います。
HTTPS のメリット
とはいうものの、やはり HTTPS 化するのは面倒。 Let’s Encrypt などで、無料の証明書も取得できるようになったとはいえ、面倒ですしデメリットばかり目立ってしまいそうです。
そこで、HTTPS のメリットを考えてみます。
HTTPS のメリットは主に以下の2つです。
- セキュリティの向上
- HTTP/2 による速度改善
1. セキュリティの向上
1つめは、言わずもがな。サイト運営者としていらないところに気を遣わないためにもセキュリティは大事です。
2. HTTP/2 による速度改善
2つめ。 HTTP/2 は速いです。
HTTP/1.x にて、CSSスプライト、JavaScriptやCSSの結合などをして速度改善の工夫していた人。僕も含めて大勢いると思います。
HTTP/2 では、そのようなまどろっこしい工夫は必要なくなります。複数のリソースを圧縮した上で複数のストリームに載せ一斉送ってくれます。この複数のリソースを送信する間、必要なTCP接続はたったの1回です。
HTTP による接続は、ハンドシェイクに SYN→SYN ACK→ACK と、通信のやり取りが3回必要です。
これに対して、HTTPS による接続は、SYN→SYN ACK→ACK、ClientHello→ServerHello、Certificate、ServerHelloDone→ClientKeyExchange、ChangeCipherSpec、Finishedという、経路を辿り、通信回数は増えます。HTTPの約倍のコストがアプリケーションデータが送信されるまでに掛かります。
これが、「HTTPS は遅い」といわれていた理由ですが、このハンドシェイクのコストを考慮しても十分勝るように HTTP/2 は設計・実装されています。効率的にアプリケーションデータを受信することができるわけです。
大事なことなのでもう一度いいます。
HTTP/2 は速いです。
HTTP/2 にする前段階として、 HTTPS 化は必須なのです。今のうちに、 HTTPS 化することで、将来のウェブサイト HTTP/2 化に備えていきましょう。
前提1: SHA-2 の証明書を使う
SHA-1 の証明書を使っている人は、ちょっと困りました。ひょっとすると、スマホのブラウザや最新のブラウザで警告が出てしまうかもしれません。
この問題に対処するには、 SHA-2 (SHA256) をハッシュアルゴリズムとして採用した SSL/TLS証明書を発行しましょう。
Let’s Encrypt を使えば、無料で発行することもできます。
前提2: リソースパス
ウェブサイトが http:// のリソースを使っていたりすると HTTPS 化した時に問題になります。
href="http://
src="http://
などで、 GREP (検索) して、 http:// の画像・CSS・JavaScript が無いように気をつけましょう。
もし、 HTTPS 化したときに http:// のリソースがあると、 Mixed content (混合コンテンツ) エラーによりリソースが表示されなかったり、鍵マークが出なかったりしてしまいます。
http:// でなければ問題になりません。対応方法は以下の4つです。
- 相対パス (./app.css など)
- 絶対パス (/app.css など)
- httpsプロトコルのみ使用 (https://example.com/app.css など)
- プロトコル指定なし (//example.com/app.css など)
ウェブサイト内のリソースを全て変えないと意味が無いので、時間を掛けてじっくりと変えていってください。
テストして実力をチェックする
今回のセキュリティテストに使ったのが、SSL Labs の SSL Server Testです。
このテストで A+ を獲得するのが今回の目標です。
まず、簡単にサーバ構築してみましょう。 Apache だと面倒くさいので、 Nginx で説明します。
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example.com-access.log;
error_log /var/log/nginx/example.com-error.log;
return 301 https://example.com$request_uri;
}
server {
listen 443;
server_name example.com;
access_log /var/log/nginx/ssl-example.com-access.log;
error_log /var/log/nginx/ssl-example.com-error.log;
root /var/www/vhosts/example.com/;
ssl on;
ssl_certificate /etc/ssl/certs/example.com.ca-bundle.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
}
前半が、 http:// でリクエスト来たら、 https:// に 301 リダイレクトするよという設定です。
そして、後半は、 https:// の設定です。 SSL の設定が最後に書かれています。認証局の中間証明書も、 ssl_certificate で指定する証明書に、追記することを忘れないでください。
では、これでテストしてみます。先程のサイトにアクセスして URL を入力してボタンを押してください。
評価 B をいただきました。 Nginx は、最近のデフォルトで、 TLS 1.0 以降しかサポートしないようになっているようです。
もし、評価が C 以下という評価の人は、
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDH !aNULL !eNULL !SSLv2 !SSLv3';
ssl_prefer_server_ciphers on;
などの設定を 後半部分に追記すると良いかもしれません。基本、古い SSL ではなくて、 TLS 1.0 以降を使うようにするのがポイントです。
A を獲得
先程のテスト結果の中の警告文を見てみましょう。「Diffie-Hellman (DH) 鍵交換パラメータが弱いので B にしといたよ」って書かれています。グラフも鍵交換のところが短く黄色で示されています。ここを解決すれば良さそうです。
今度は、評価 A を奪いに行きましょう。より強固な鍵交換パラメータ dhparam を新たに生成する必要があります。
# cd /etc/ssl/private
# openssl dhparam 2048 -out dhparam.pem
# chmod 600 dhparam.pem
こうして、 Nginx の設定をします。
ssl_dhparam /etc/ssl/private/dhparam.pem;
Nginx を再起動して、もう一度、テストしてみましょう。
どやぁ。
評価 A をいただきました。
A+ を獲得
更に、評価を A+ にして、満足感を味わいましょう。
先程の設定の最後に以下の一文を追記しましょう。
add_header Strict-Transport-Security "max-age=15768000; includeSubdomains";
「サブドメインも含めて (includeSubdomains) 、 HTTPS を使い続けます」というヘッダを強制的に挿入します。http:// のURLにアクセスしようとしても、ブラウザが自動的に https:// としてアクセスします。
ただし、これをしていいかどうかは、よく検討しましょう。サブドメインのサイトまで HTTPS での接続が強制される形になります。
どうでしょう。評価 A+ をいただきました。
これで、既知の攻撃をかなり予防することができたのではないでしょうか。SSL Labsのお墨付きをいただいたということであります。
まとめ
HTTPS にすることで、セキュリティを得たサイトを更に安全にすることができました。HTTPS は、速度的なデメリットではなくて、 HTTP/2 に対応することでメリットとなりうることを説明しました。
SSL Server Testですが、多くのサイト管理者が気にする指標のようですね。よく見るようになった気がします。ぜひ、この流れに乗って、お持ちのウェブサイトを検査・改善してみてはいかがでしょうか。
この記事を読んだあとに
- 書いた人のツイッター – Follow me!
- 『売上を3年連続20%成長させた18の秘訣』
- 運営しているアクションゲーム