5分でわかる正しい Web サイト常時 SSL 化のための基礎知識

Web サイトを常時 SSL 化する場合に、最低限知っておかなければならない知識や、注意点、実際の設定方法まで、ひと通りまとめてみました。メリットやデメリット、証明書の種別からリダイレクト設定などについても解説しています。

HTTPS をランキングシグナルに使用しますと Google が公式に発表したあたりから、Web サイトの SSL 対応、特に Google が推奨している Web サイトをすべて HTTPS で配信する、所謂 「常時 SSL 化」 についての話を聞いたり、実際にお客様から相談されたりするケースが増えてきました。

そこで、いい機会だしその辺に関する情報をまとめておこうかな~ と思って書いてみた、恒例の (?) 5分でわかるシリーズ。書き終わって見たところ絶対に 5分じゃ無理っていう文章量になっててどうしようかなぁとも思ったんですが、気にせず公開してみます。

常時 SSL とは

「常時 SSL」 という言葉がいつごろから使われているのかはわかりませんが、簡単に言っちゃえば Web サイト内の全ページを HTTPS で配信しましょうって意味で広く使われているみたいですね。

「常時」 なので HTTPS でのみ Web サイトを公開して、HTTP 接続は禁止するってところまで含むのかもしれませんが、ざっと調べてみた限りでは、同じサイトに HTTP でも接続できるかできないかは特に問わないみたいです。

さて、上記を踏まえると、全ページを HTTPS で配信するにしても下記のように 2通りの方法が考えられます。

  1. HTTPS でのみ Web サイトを配信する (リダイレクトや HSTS の利用により HTTPS を強制)
  2. HTTP と HTTPS の両方で配信してユーザーが選択できるようにする (一部は HTTPS 強制含むとして)

とはいえ、わざわざ面倒なことをすることはないので、通常は 1番目の方でよいと思いますから、本記事でいう、「常時 SSL 化」 というのはそれを前提に書いていきますが、場合によっては HTTP での接続を可能にしておいた方がよい場合もありますので、その辺は後述します。

正しい知識で常時 SSL 化を行うために

根本的なところですが、新規の場合なら Web サイトの企画や制作の準備段階で、どのように SSL を導入するのか、あるいはどの範囲まで SSL で保護すべきか、などを見極め、確定させることが重要です。常時 SSL 化が本当に必要なのか、逆に HTTP でのみ配信する方がよいページはないのか...... などです。

既存の Web サイトが対象の場合はこれに加えて必要になる Web ページやシステム側の改修を含めた対応についても事前にきちんと確認しておく必要があります。

例えば、他に理由がないにもかかわらず、SEO のためだけに Web サイトを常時 SSL 化しようみたいなことであればやめておいた方がいいです。大した意味はありませんし、いい加減な導入をすると、盗聴・パケット改竄の防止、なりすましの防止といった SSL 導入の本来の目的を果たせないばかりでなく、Web サイトの運用に影響が出る場合もあります。

その辺を踏まえて、この記事では、Web サイトを常時 SSL 化 (常時じゃなくても) する場合に、最低限知っておかなければならない知識や、注意点、実際の設定方法まで、ひと通りまとめてみました。

タイトルに 「正しい」 とか入れて、無駄にハードルを上げていますが、間違っている点などがあればご指摘ください。


それでは始めますが、まずは長いので目次を。

全体としては長いですけども、各大セクション冒頭に書いてある 「要点」 ってところだけ読めば、ある程度はわかると思います。全文を 5分で読むのは無理だと思いますが、要点だけなら 5分でいけるはず (よってタイトルに偽りなし...... ということで)

  1. 常時 SSL 化のメリットと目的を考える
  2. SSL サーバ証明書の選択
  3. 証明書のオプションを選択
  4. ここまでのまとめ
  5. SSL 導入にあたっての注意点
  6. SSL 導入後の作業

常時 SSL 化のメリットと目的を考える

要点:
常時 SSL 化のメリットは盗聴やパケット改竄をサイト全体で防止したり、なりすましの防止。常時 SSL にしたらすべて安心というわけではないが、正しく導入すればメリットは大きく、Web サイト全体の信頼性や安全性を向上させることが可能。また、SEO 的なメリットも少しだけ期待できそう。

常時 SSL 化のメリットとしては下記のようなことが挙げられます。

  1. 下記を、Web サイト全体で防止できる
    • 盗聴の防止
    • パケット改竄の防止
  2. なりすましの防止
  3. ブラウザにおける表示方法変更への備え
  4. SEO におけるメリット

盗聴やパケット改竄の防止

盗聴やパケット改竄の防止については、常時 SSL か、一部 SSL かに関わらず重要なメリットですが、常時 SSL にしてしまうことで、Web サイト全体で対策を行えます。

元々、HTTP で接続している場合は常に、経路上で盗聴されたり、中間者攻撃を実行される可能性があります。しかし、単に Web ページを閲覧しているだけであれば、そのリスクに晒されていたとしても大きな問題は起きません。

しかし、ユーザーが重要な情報をサーバに送信したり、サーバと秘匿性の高いデータをやりとりする場合にはそれでは大問題ですし、それを防ぐために HTTPS で通信するわけですが、Web サイト内の一部だけを SSL 化した場合、間違った実装がされると、本来の目的である通信の保護が正常に機能しない場合があります。

例えば、入力画面は HTTP で配信され、フォームの送信先だけが HTTPS になっているような場合 (ログインフォームが全ページに設置されているなんて場合によくあるパターンですね)、HTTP で配信されているページのフォームから送信されるデータは、経路上のパケット改竄によって送信先を書き換えられたりすることで、盗聴される可能性があります。

あるいは、HTTP 接続時、中間者攻撃によって偽の Cookie をセットされた場合など、サーバがその Cookie をそのまま受け入れてしまうことでユーザーが危険に晒されるといった可能性もあります。

もちろんこれらは入力画面を HTTPS で配信しないとか、Cookie の処理が適切でないなど、実装上の問題ではありますが、全ページにわたる常時 SSL 化と、適切な設定をすることで、このような心配を (完全にではないですが) しなくて済むようになります。

なりすましの防止

なりすましの防止に関しては、常時 SSL 化が直接的に防ぐというよりは、ユーザーが他の不正なサイトに誘導された場合に気がつく可能性を上げたり、フィッシングサイトを作る際の難易度を上げることで、結果として防止につなげていくという感じですが、後述する EV SSL 証明書を利用したりすれば、かなり強力な対策となります。

これはなりすましの被害に遭いやすい大企業 (銀行やクレジットカード会社のようなお金を扱う企業も含め) や有名ブランドの Web サイトにとっては大きなメリットかもしれません。

ブラウザにおける表示方法変更への備え

以前、当 Blog でも取り上げましたが (下記リンク参照)、Google は、HTTP 接続時は特に何も表示せず、HTTPS で接続しているときに 「今、安全な接続をしています」 とアドレスバーの鍵マークなどで知らせる従来の表示方法をやめ、HTTPS 接続時を通常状態として、HTTP で接続したら 「今、安全でない接続をしています」 と表示する方法に改めない? という提案をしています。

まだ、Chrome でそういう表示にすることが提案されているという段階ですし、他のブラウザベンダがこれに追随するかはわかりませんが、Google は Chrome での具体的な導入について今年着手したいとも言っていますので、もしですが、HTTP 接続が安全でないと表示されるような仕様になった場合、ユーザーに不安を与えないためにも、特に企業のサイトなどは HTTPS がほぼ必須になるかもしれません。

常時 SSL 化しておけば、そういう変更がもしあった場合でも慌てなくて済むかもしれません。

SEO におけるメリット

あとは、おまけ的な効果として、近年は SEO 的なメリットがほんのちょっとだけあるそうで。これは Google さんが公式に発表しています (下記リンク参照) が、Google は Web サイトの安全性を、優れたユーザー体験を実現する要素の 1つとして考えているようで、HTTPS で配信される Web サイトを少しだけ優遇してくれるとのこと。

ちなみに、HTTPS を評価に使用する場合、Web サイト全体が HTTPS で配信されているかではなく、あくまで各ページ単位で見ますよと言っていますので、全サイトを常時 SSL 化することが必要というわけではありません。

とはいえ、前述した Chrome の件もそうですが、Google さんはかなり強力に Web ページの常時 SSL 化を推進していますので、対応を前向きに検討すべき材料は揃っています。

デメリットはないの?

逆に常時 SSL 化のデメリットも考えてみます。

まず、暗号化通信は多少サーバ、クライアント双方に負荷をかけます。昔は SSL で暗号化するとサイトの表示が遅くなるなんて言われましたが、今どきそれで目に見えてパフォーマンスが落ちるような環境はないと思ってよいと思いますし、逆に SPDY や HTTP/2 (over TLS)が使用できる環境であればパフォーマンスが向上する可能性もあります。

あとは当然、コスト的な負担があることですが、これは Web サイトの種類や役割によりますし、必要なサイトであればどんなにコストがかかろうと対応しなければならない場合もあるので、デメリットという感じではないですかね。導入・設定などを行うのに専門的な知識が必要っていう点も同様に、導入障壁にはなるかもしれませんがデメリットとは言えないと思います。

あと、これは後述しますがサーバ側の設定の仕方によって、一部の環境で Web サイトにアクセスできなくなる可能性もあります。主に今ではもうほとんど使われていないような旧式の環境のみが対象ではありますが、一応デメリットにはなるのかもしれません。

そんなところでしょうか? 目立ったデメリットはなさそうです。

さて、常時 SSL 化のメリット、および考えられるデメリットがわかったところで、次のステップとして、まずは SSL 導入時に必要な、SSL サーバ証明書の種別について次のセクションでおさらいしてみようと思います。

SSL サーバ証明書の選択

要点:
様々な認証局、及び認証レベルで証明書は販売されているが、暗号強度的にはどれも同じ。社会的な信頼をどのレベルで求めるかで証明書の種類を選択。会社の公式サイトなら実在証明が行われる組織認証 SSL、さらに大企業なら EV SSL、Web サービスや情報サイトならドメイン認証 SSL など。

ここではどの認証局 (CA:Certification Authority) がいいとか言う話ではなく、大まかな証明書の種別と、その選択の仕方について解説していきます。

認証局については、有名どころだとベリサイン (今はシマンテック) さんとかジオトラストさん、グローバルサインさん、セコム (トラストシステム) さんなど数多くありますし、その代理店を含めると、証明書を導入しようとして検索した際には多くの選択肢が出てきます。

さらに、各認証局で、数種類の SSL サーバ証明書をサービスとして展開しているので、詳しくない人にとってはどれを選んだらいいの? ということになりがちです。また、価格も年間 10万円を超えるものから、数千円、場合によっては無料のものまで、幅広く、これも選択の基準がわかりにくい点かと思います。

認証レベルによる証明書の分類

証明書は、認証レベルの違いにより、下記の 3種類に分類されます。

  1. ドメイン認証 (Domain Validation) SSL 証明書
  2. 組織認証 (Organization Validation) SSL 証明書
  3. EV (Extended Validation) SSL 証明書

1から順に認証レベルが高くなります。つまり EV SSL が認証レベルとしては最高。ですが、暗号強度、つまり通信を保護する強度についてはここでは関係ありません。あくまで証明書が発行される際にどのレベルまでチェックされていますかという話で、機能的な信頼度ではなく、社会的な信頼度のレベルと言えます。

ドメイン認証 SSL 証明書

ドメイン認証は、そのドメイン (CSR に記載のコモンネーム) の所有者確認のみ行って発行するものです。

例えば、この Blog のドメインである 「hyper-text.org」 で証明書を取得しようと私が申し込んだ場合、このドメインを私が所有していることさえ証明できれば、証明書が発行されます。

所有者確認の方法は様々ですが、例えば 「申し込んだドメインの postmaster@ や info@ など代表アドレスにメールを送るから、受け取ったらメールに記載の確認 URL にアクセスしてね。」 といった方法や、「サーバの該当ドメイン直下に決められた HTML ファイルなどを設置して、それをクロールで確認できたら (Google ウェブマスターツールなどでも使われるあれです) 所有者確認とします。」 的なものなどが代表的です。

ドメイン認証の利点は低コストな点です。人が書類審査をしたりしなくてよいので、すべてプログラムで処理することで認証局側の事務コストを省き、その分価格も安く提供しているところが多いというわけです。証明書の発行自体も早ければ数分で完了します。

ただし、組織の確認はしませんので、証明書に組織情報は記載されません。下記は Firefox でドメイン認証型の証明書情報を表示した例ですが、組織情報が記載されていないことがわかります。

ドメイン認証 SSL 証明書の情報を表示した例。組織情報が記載されていません。

このタイプの証明書は年間数千円から、高いものでも 2、3万円程度で購入できますので、コスト的には非常にお得な証明書になります。中には StartSSL のように無料のものもありますし、Mozilla や Cisco Systems が共同で立ち上げた Let's Encrypt も同様に無料の証明書を発行する予定です (今年の第二四半期からスタート予定)。

ドメイン認証 SSL はそのコストの安さを活かして複数年をまとめて購入し、サーバ証明書の更新の手間を減らすという手も使えます。3、4年の有効期限で購入しても 1万円もいかない場合もありますし、仮に有効期限内に使わなくなったり、暗号強度的に新しいものが出て刷新するとなっても大して痛くないです。

組織認証 SSL 証明書

上記、ドメイン認証と同様にドメインの所有者確認は当然として、さらにその所有者が実在する組織かということを、第三者データベース (帝国データバンクなど) の情報や、登記簿謄本や印鑑証明など証明書類の提出などによって身元確認した上で発行される証明書です。

色々と書類を提出して確認してもらったりと手間もかかりますし、時間もかかりますが、証明書にも確認が取れた組織名が記載されますし、ユーザー側から見てもドメイン所有者の身元確認が取れているということでより安心できます。

組織認証 SSL 証明書の情報を表示した例。組織情報が証明書に記載されているのがわかります。

ただし、事務処理コストもかかる分、証明書の金額も高くなります。5、6万円以上で販売されている証明書は大体このタイプです。

EV SSL 証明書

日本語でいうと、拡張認証 SSL 証明書でしょうか。組織認証 SSL 証明書で行う確認作業に加え、電話での本人確認など、定められた EV 証明書ガイドラインに則ってより厳格な審査が行われた上で発行されます。このタイプの証明書を使用すると、対応ブラウザではアドレスバーが緑色に変わり、組織名が表示されて EV SSL を使用していることがわかるようになっています。

これによって、より信頼性の高い証明書が使われていますよとユーザーに知らせることができますし、後述しますが、これがきちんとユーザーに周知されていれば、フィッシングなどで別サイトに誘導されても気がつく可能性が高まります (下記は三井住友銀行さんの例)。

EV SSL 証明書の情報を表示した例。ブラウザのアドレスバーが緑色に変化し、より信頼度の高い証明書が使われていることを示しています。

認証レベルが高ければ安全ということではない

値段が高い SSL 証明書を使っているんだから安いのよりも安全だろと思うかもしれませんが、前述したとおり暗号強度に関していえば認証レベルとは関係がなく、どれも差はありません (実際の暗号強度を決めるのは公開鍵長)。

また、証明書は今アクセスしているドメインと証明書が一致していて、その証明書が第三者によって審査されているものですよと保証はしてくれるものの、そのドメイン自体が悪意のあるサイトか、そうでないかについては関知しません。

例えば銀行のサイトのドメインに似せたドメインを取って、それで証明書を取得し、SSL で保護されたフィッシングサイトを作ることもできます。つまり、SSL で保護されていれば必ず安全なサイトとは限りませんので、ユーザー側も注意が必要です。

ただし、認証レベルが高い証明書のメリットもあります。例えば悪意ある人がフィッシング目的で証明書を取ろうと思っても、ドメイン認証型であれば取得する難易度が低くても、組織認証型であれば犯罪を犯そうと思っている人にとっては身元確認が大きな障壁ですし、EV SSL に至っては詐欺目的で取ろうとする人はまずいないと思います。

ですから、企業が EV SSL を使用していて、それがユーザーに十分に認知されている場合、悪意ある人がフィッシングを仕掛けようとする難易度は相当に上がるかもしれませんし、それが抑止力になる可能性もあります。とは言ってもユーザーが自分がアクセスしているサイトのドメインや証明書を確認しなければ、引っかかる時は引っかかりますので、過信は禁物ですけども。

その点を踏まえて、

  • 一般には非公開のサイト、あるいは決済システムなどを伴わない Web サイトや Web サービス、個人事業主や中小・零細企業のサイト (問い合わせフォームくらいしかないみたいな) などでは、ドメイン認証 SSL で十分かも。
  • ある程度の規模の企業や組織では組織認証 SSL が最低限必要かも。
  • 大企業や銀行などの重要な情報を扱うサイトでは、EV SSL の導入が必要かも。

といった感じで、使用するサイトの状況や組織の規模、社会的立場に合わせて選択するのがよいと思います。

証明書のオプションを選択

要点:
証明書に、ワイルドカードやマルチドメインというオプションを提供している認証局もある。同一ドメイン上のサブドメインもまとめて暗号化通信の対象にしたい場合はワイルドカード証明書、同一サーバ上で運用するすべてのドメインでまとめて暗号化通信を使用したい場合などはマルチドメイン証明書を利用するとよいかも。

ワイルドカード証明書とは

認証局によっては、オプションでワイルドカード証明書の発行に対応している場合があります。ワイルドカード証明書とは、コモンネームにワイルドカードを使用し、1つの証明書で、複数のコモンネームに対する暗号化通信を可能にします。

通常、コモンネームは 「hyper-text.org」 などとして証明書を発行しますが、この証明書は 「www.hyper-text.org」 や 「blog.hyper-text.org」 では使用できません。これらで使用したい場合は、別途証明書を個別に発行する必要があります。

ワイルドカード証明書は、コモンネームを 「*.hyper-text.org」 などとして証明書を発行することで、「hyper-text.org」 だけでなく、「hoge.hyper-text.org」 でも同じ証明書を使えるようにしたものです。同一ドメインで多くのサブドメインを運用していて、それらすべてを SSL で保護したい場合などはコスト面からも、手間の面からも、とても便利な仕組みと言えます。

マルチドメイン証明書とは

これも認証局によってですが、オプションでマルチドメイン証明書の発行に対応している場合があります。1つのサーバで複数のドメインを運用していて、それらでまとめて暗号化通信を行いたい場合などは、マルチドメイン証明書が使えると、取得費用や管理コストが抑えられるかもしれません。

ここまでのまとめ

ここまでで、サーバ証明書の種類 (必要な認証レベル) と、必要に応じてワイルドカードなどのオプションが必要かどうか、までは決まったと思います。

あとはブランド認知や価格などで認証局を選択すればよいと思います。例えば同じ組織認証 SSL 証明書でも、ブランドによって価格は異なりますが、証明書の機能的には同じです (もちろんサポート体制などは差があると思いますし、EV SSL の中には、脆弱性診断が付加機能としてついてくるものもあるみたいですが、証明書とはまた別の付加価値です)。

証明書の発行シェアで圧倒的に高いのはベリサイン (シマンテック) ですが、日本ならセコムさんとかホームセキュリティの方で認知されていてなんか安心なイメージあったり...... わからなければ有名なところで選んだらいいと思いますし、ドメイン認証 SSL 証明書で安いところがいいみたいな感じであれば、例えば RapidSSL さんなんかは私の会社のサイトで使っていたりします。

それから、有名どころの認証局では、証明書を購入すると、Web サイトに掲載できる、SSL 証明書導入を示すための 「サイトシール (呼び名は様々かもしれません)」 が発行されるものもあります。大した意味はありませんが (とか言うと怒られそう......)、少しでもユーザーに安心感を与えたい場合は、大手のシールを貼っておくと効果があるかもしれませんね。もちろん、シールの有無などより、正しく設定や運用がされていることの方が最重要ですが。

SSL 導入にあたっての注意点

さて、証明書の種別が理解できたところで、サーバ証明書を選択して導入する際、バーチャルホストで運営されているサーバで知っておかなければならない制約や、コンテンツ制作時の注意点などについて簡単に触れておきましょう。

要点:
新規の証明書は 2048bit RSA / SHA-2 で発行。1台のサーバで複数の証明書を使用したい場合はサーバ、および閲覧環境の SNI 対応に注意。また混在コンテンツに注意すると共に、外部スクリプトの読み込みなどは無制限に行わない。場合によっては CSP の導入も検討。

公開鍵暗号とハッシュ関数

詳しいことを書き始めると長くなるので簡単に書きますが、これから新規に発行する場合、証明書の公開鍵暗号は 2048bit RSA、ハッシュ関数は SHA-2 を選択します。メジャーな認証局で証明書を発行しようとすれば自然とそうなると思いますが、確認しましょう。

この辺の話は、下記のリンク先などが参考になると思います。

SNI (Server Name Indication) とは

SNI (Server Name Indication) は、グローバル IP アドレス単位ではなく、同一 IP アドレス上で、ホスト名単位で別々の証明書を使い分けることを可能にする SSL/TLS の拡張仕様で、RFC 6066 内で定義されています (該当箇所の日本語訳)。

簡単に言ってしまえば、本来、証明書はグローバル IP アドレスごとにしか使えませんでした。しかし、バーチャルホストで同一サーバ上に複数のホストを持つ (つまり全ホストが同一の IP アドレスになる) ことは近年では当たり前で、この制約があると、運用上、色々と面倒です。

もちろん、1台の物理サーバに対して複数のグローバル IP アドレスを割り当てること自体はできますが、コスト面などを考えればほとんどの Web サイトで現実的ではありません。

そこで TLS を拡張し、バーチャルホストと同じように、リクエストに応じて証明書を出し分けることができるようにしたのが SNI です。サーバ、クライアントの双方が SNI に対応している必要はありますが、この機能によって、証明書ごとにグローバル IP アドレスが必要という制約から解放されます。

SNI に対応しない環境とその挙動

SNI は、現時点で主要なサーバソフトウェアや、PC 向けブラウザにおいては、ほぼ実装されていて特に問題になることはありません。しかし、携帯電話 (所謂ガラケー) や、PC やスマートフォン向けでも旧式のブラウザ、OS が対応していない場合があります。

とは言っても、IE6 とか、Windows XP 以前で稼働する IE、Android 2.x 以前の標準ブラウザとか、シェア的にももう終わった感じの環境が対象ですので、通常は気にしなくてもよいと思いますが、対象サイトの利用環境によっては事前に検討が必要かもしれませんので注意しましょう。

SNI に対応しない環境で、複数の証明書が設定されたサーバ上のホストを閲覧した場合、基本的にはデフォルト設定されたバーチャルホストの証明書が使用されます。つまり、デフォルト設定のバーチャルホストに対して接続したのであれば何ら問題はありませんが、そうでない場合は証明書の不一致によりブラウザ上に警告が出てしまいます。

Apache を例にすると、例えば下記のようなバーチャルホストの設定がされていたとして、

<VirtualHost *:443>
  SSLEngine on
  ...中略...
  DocumentRoot /var/www/html/burnworks
  ServerName burnworks.com
  ServerAlias www.burnworks.com
</VirtualHost>

<VirtualHost *:443>
  SSLEngine on
  ...中略...
  DocumentRoot /var/www/html/hyper-text
  ServerName hyper-text.org
  ServerAlias www.hyper-text.org
</VirtualHost>

この場合、デフォルトのバーチャルホストは最初に書かれている 「burnworks.com」 になります。

ですから、SNI 未対応ブラウザでも、

https://burnworks.com/

にアクセスする分には問題なく閲覧できます。しかし、

https://hyper-text.org/

にアクセスすると、リクエストに対してデフォルトバーチャルホストである、「burnworks.com」 の証明書が帰ってしまいますので、「この証明書は別のアドレス用に発行されたものです」 的なエラーが表示されます。

よって、SNI 未対応ブラウザを動作環境から外すにしても、デフォルトバーチャルホストの設定によって、最低限メインのサイトだけにはアクセスできるようにしときましょうといった配慮が必要になるかもしれません。

混在コンテンツに注意

HTTPS で配信する Webページ上では、外部から読み込むリソース (例えば画像や CSS、JavaScript や iframe など) もすべて HTTPS で配信される必要があります。

折角、HTTPS で Web ページを配信していても、その中に HTTP で配信されているコンテンツが含まれていた場合、その HTTP コンテンツが攻撃者に盗聴されたり、改竄されてユーザーが危険にさらされる可能性があります。このような、HTTPS で配信されるコンテンツ内に混在する HTTP コンテンツを、「混在コンテンツ (Mixed Content)」 と呼びます。

そこで、主要ブラウザには、この混在コンテンツが存在する場合、混在コンテンツの読み込みや実行をブロックする機能が実装されていたり、混在コンテンツがあるとアドレスバーで警告する機能が実装されています。

下記は Chrome で混在コンテンツの警告が表示されている例です。他のブラウザも表示の仕方は異なりますが、同様の表示をして警告します。

Chrome で混在コンテンツの警告が表示されている例

これを避けるため、同じドメイン上から読み込まれるリソースに関しては、下記のように絶対パス、あるいは相対パスで記述しておけばよいですし、

<!-- link 要素の例 -->
<link href="/css/style.css" rel="stylesheet" />
<link href="../css/style.css" rel="stylesheet" />

<!-- img 要素の例 -->
<img src="/img/sample.jpg" alt="" />
<img src="../../img/sample.jpg" alt="" />

CDN など外部のサーバからリソースを読み込む場合も、配信元が HTTPS で配信しているのであれば、下記のように読み込んでおけばよいでしょう。

<!-- スキームを省略して読み込み -->
<link href="//example.com/css/style.css" rel="stylesheet" />

<!-- あるいは https スキームを指定 -->
<link href="https//example.com/css/style.css" rel="stylesheet" />

<!-- Google CDN から読み込む例 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

<!-- スキームを省略する場合 -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

外部リソースの読み込み自体の安全性

Web ページを SSL で保護したとしても、外部からスクリプトや iframe を読み込んでいる場合、それら外部サイトがハッキングされた場合など、悪意あるスクリプトをサイトに注入される可能性があります。これは外部リソースが HTTPS で配信され、前述した混在コンテンツの状態になっていなかったとしても同様です。

特に EV SSL を使用している環境では、緑色のアドレスバーや組織名を表示して非常に安全な接続がされているとユーザーに思わせておいて、実はその Web ページ内には自社が管理していない、外部企業が提供するコンテンツが大量に読み込まれてますなんてことになると、何のための EV SSL かわからなくなります。

これが Google や Facebook など、ある程度信頼がおける企業が公式に提供する外部リソースならまだましです。

例えば、jQuery などを配信している Google Hosted Libraries で使われている ajax.googleapis.com や、Google Analysis のトラッキングコード配信に使われている google-analytics.com の SSL 証明書は組織認証 SSL で、Google としての組織認証があり信用度は高いですが (もちろん、Google 自体の社会的信頼度が高くないと意味がないですが)、ドメイン認証 SSL であれば簡単に取得できますので、HTTPS で配信されているとしても、中には運営組織がはっきりしないサーバから配信されているスクリプトもあります。

そのようなコンテンツを不用意に読み込んでしまうと、ブラウザの表示上は安全って言ってるけど、実は全く安全な接続じゃなかったなんて最悪の事態にもなりかねませんし、安全でないにもかかわらず、ユーザーに 「この接続は安全です」 などと表示するべきではありません。

Web ページは SSL で保護したし、混在コンテンツもないから安心...... とばかりは言えないですので、制作時や運用時におけるガイドライン作成とその遵守なども重要になります。この辺が見落とされておろそかになっているケースも多いので、注意が必要でしょう。

CSP (Content Security Policy)

また、前述のように Web サイト制作者側で意図して外部リソースを読み込んだなら修正すればよいだけですが、XSS (クロスサイトスクリプティング) などによって意図せず外部リソースが注入される可能性もあります。

もちろん、XSS は Web サイトで稼働するアプリケーションに何らかの脆弱性がなければおこらないので、アプリケーション側での対策が重要なのは当然ですが、同時に万が一外部からスクリプトが注入されても、最悪その実行だけは遮断するための対策を施しておくこともできます。

そこで、Content Security Policy (CSP) です。

CSP は、あらかじめその Web ページで読み込まれることが想定されている JavaScript などのコンテンツを、ホワイトリストとして指定することによって、攻撃者によって挿入される悪意のあるスクリプトの読み込みや実行を遮断し、XSS など、インジェクション攻撃から Web サイト や Web アプリケーションを保護するための仕組みです (Content Security Policy 1.0 の仕様はこちら)。

ちょっと SSL の話題とはずれますし、ここで詳細を説明すると長くなるため端折りますが、詳しくは下記の記事をご覧ください。少しだけ古い記事 (2013年) ですが、CSP の仕様や実際の指定の仕方などについて簡単にですが書いています。

SSL 導入後の作業

さて、サーバに証明書がインストールされ、実際に HTTPS でコンテンツの配信する準備ができたとして、サーバ側で行うべき対応と、その他、必要と思われる作業についてまとめます。

要点:
サーバサイドでのリダイレクト設定で HTTPS に集約。HSTS で対応ブラウザに対しては HTTPS 接続を強制する。Cookie に Secure 属性を付けるのを忘れずに。既存サイトの場合は Google ウェブマスターツールの再設定などが必要になるかも。

HSTS (HTTP Strict Transport Security) とは

HSTS (HTTP Strict Transport Security) は、「このサイトに接続するときは HTTPS を使ってね」 という HTTP レスポンスヘッダをブラウザに送信することで、HTTPS での通信を強制するものです。

現状では IE 以外のモダンブラウザはほぼ HSTS に対応していますが、このレスポンスヘッダ (Strict-Transport-Security ヘッダ) を受け取ったブラウザは、そのドメインに対しては強制的に HTTPS で接続しようとします。

厳密にはそのサイトが始めてアクセスするサイトで、HTTP で接続した場合には、Strict-Transport-Security ヘッダを受け取るまでの間 HTTP で接続されますが、一度ヘッダ情報がブラウザにセットされれば、以降はそれをクリアしない限り、HTTP では接続できなくなります。

HSTS の設定については、下記の記事で詳しく書いていますので、参考までにどうぞ。

HSTS Preload List (HSTS プリロードリスト)

なお、対応ブラウザ (Firefox、Chrome、Safari) 向けに、あらかじめこのドメインでは HSTS が設定されていますよと知らせておく HSTS Preload List についてと、それを登録するためのフォームを、Google の Ilya Grigorik 氏が Google+ に投稿しています。

If you want your site to be in Chrome's HSTS preload list... by Ilya Grigorik - Google+

前述の通り、Strict-Transport-Security ヘッダがセットされていない初回のアクセスだけはセキュアじゃないんですが、これに登録しておくと、ブラウザ側で事前に情報を持っていてくれて、HTTPS で接続してくれるとのこと。

ただし、下記の条件があります。

  1. Have a valid certificate.
  2. Redirect all HTTP traffic to HTTPS - i.e. be HTTPS only.
  3. Serve all subdomains over HTTPS.
  4. Serve an HSTS header on base domain:
    • Expiry must be at least eighteen weeks (10886400 seconds).
    • The includeSubdomains token must be specified.
    • The preload token must be specified.

HSTS Preload Submission から引用

  1. 有効な証明書
  2. すべての HTTP アクセスを、HTTPS にリダイレクトしている
  3. サブドメインも含めてすべて HTTPS で配信している
  4. ベースドメイン上で下記の HSTS ヘッダを送信している
    • 有効期限が、18週間 (10886400 秒) 以上
    • includeSubdomains オプションを付与
    • preload オプションを付与

ということで、例えば下記のような感じでヘッダをセットしていれば大丈夫そうなんだけど、RFC 6797 には preload オプションのことは書いてないみたいなのでちょっとよくわからんです。

<VirtualHost *:443>
  SSLEngine on
  ...中略...
  Header set Strict-Transport-Security "max-age=315360000;includeSubDomains;preload"
  DocumentRoot /var/www/html/burnworks.com
  ServerName burnworks.com
  ServerAlias www.burnworks.com
</VirtualHost>

ちなみに、includeSubdomains オプションを付けた場合は、指定したドメインのサブドメインも含めて、すべて HTTPS が強制されますので、すでに HTTP で公開しているサブドメインのサイトがある場合など、稼働中のサーバで設定する場合は注意が必要です。

また、例えばあるサブドメインのサイトが、実際に Strict-Transport-Security ヘッダを送信したサーバとは別サーバで稼働していて、このサーバでは特に Strict-Transport-Security ヘッダを送信していなかったとしても、ヘッダ情報はブラウザに保存されるため、このサブドメインに対しても HTTPS でしか接続できなくなります。あとからサブドメインでサイトを立ち上げる場合は注意が必要です。

リダイレクト設定

HSTS の設定を行うことで、対応ブラウザについては HTTPS での接続を強制できますが、未対応ブラウザでは HTTP での接続ができてしまいます。

これは Google などのクローラーも同様で、検索結果では HTTP で配信されたコンテンツが残り続けることになるかもしれません (一応、Google は HTTP / HTTPS 両方でコンテンツがインデックスされている場合、https:// の方を優先して検索結果に表示するみたいですが)。

HTTPS で全コンテンツが正しく閲覧できることが確認できたら、サーバサイドでリダイレクトを設定して、HTTPS で配信しているコンテンツにアクセスを集約するのがよいと思われます。

Apache 側で設定するなら、例えば .htaccess に下記のように記述して設置します。

# 443 ポート以外で接続されたら https:// へリダイレクト
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{SERVER_PORT} !^443$
  RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
</IfModule>

下記のような書き方でも同じ。

# HTTPS が off で接続された場合 https:// へリダイレクト
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
</IfModule>

httpd.conf で設定してもいいと思います。

特に元々 HTTP で配信していた既存サイトの場合は URL の正規化やら気になるところですが、一応、きちんと 1 対 1 で対応しているページ (要するに HTTP / HTTPS 両方に同じコンテンツがある状態) を 301 ステータスでリダイレクトする分には、SEO 的にも問題ないみたいですので、これでいいんじゃないでしょうか。

本当なら 80番ポートを閉じちゃって、HTTP での待ち受け自体をしないのが正しいのかもしれませんが、それだと HSTS に対応していない環境などで HTTP アクセスされた場合に不親切ですし、元々 HTTP で配信されていた既存サイトの場合は現実的に無理ですしね。

Cookie に Secure 属性を付ける

Secure 属性のついた Cookie は、HTTPS で接続しているときのみ、Web サーバに送信されます。よって、HTTP 接続時に Cookie が送信され、盗聴されることはなくなります。逆に言えば、常時 SSL 化しても、Cookie に Secure 属性がついていなければ、Cookie 盗聴のリスクを負うことになります。

例えば PHP なら、session.cookiesecure で設定するなどすれば、Cookie に Secure 属性を付けることができます。ついでに、クライアントスクリプトから Cookie にアクセスする必要がなければ、session.cookiehttponly で HttpOnly 属性を付与するなど、Cookie の盗聴や改竄を防ぐための対策も施しておくとよいと思います。

Secure 属性がついていないとどうなるの? という点については、Cookie の盗聴や改変について書かれた、徳丸氏の下記の記事が参考になります。

Google ウェブマスターツールの設定など

Google ウェブマスターツールは HTTP / HTTPS をそれぞれ別々に登録するようになっていますので、登録していない場合はしておきます。既存サイトを常時 SSL 化した場合は、ここで https:// でのインデックス状況などを確認していく必要があるかもしれません。

また、「もともと HTTPS で配信するページにはログイン画面などがあったので、robots.txt でクローラーがアクセスしないようにしていました」 とか、「noindex メタタグでインデックスをされないようにしていました」 なんて場合は、常時 SSL 化したあとも設定を解除するのを忘れていると困ることになりますので要確認です。

あと、例えば Movable Type や WordPress など、CMS でサイトを管理している場合は、URL の設定項目などに http:// が残っている場合がありますので、その辺も忘れずにチェックしましょう。

sitemap.xml なども、CMS で生成している場合は、上記の設定が残ったままだと Google に送信される URL が http:// のままになってしまうかもしれません。

その他、自分で修正できる範囲で外部から張っているリンクの URL を直すとか (SNS のプロフィール欄からリンクしてるとか、サテライトサイトからのリンクとか......)、細かい点ですが特に HTTP で配信されていた既存のサイトを常時 SSL 化した際はきちんと確認する方がよいと思います。新規で立ち上げたドメインならほとんど修正するところはないと思いますが。


さて、長かったですね...... 安易な気持ちでまとめようと思って書き始めたら、思ったより長くなった結果、途中で飽きたりして結局 3日くらいかかっちゃいました。仕事の合間にちょっとずつ書いているとはいえさすがに長すぎます。それだけ、一言で SSL といっても知っておくべきことが多いということなんでしょうが。

ということで、常時 SSL 化を検討中の方に、何かしらの参考になれば幸いです。


関連エントリー

記事をここまで御覧頂きありがとうございます。
この記事が気に入ったらサポートしてみませんか?