常時SSL化（AOSSL）に向け、合わせて点検・対応すべきこと

　こんにちは、y-okudaです。
　**[ファーストサーバ Advent Calendar 2016](http://qiita.com/advent-calendar/2016/firstserver)**の2日目を担当することになりました。書いているうちについつい長い記事になってしまい恐縮ですが、この内容が少しでもどなたかのお役に立てれば幸いです。

　昨年あたりからインターネット界隈では**常時SSL化**というキーワードが賑わっています。これは何か？とひとことで言うと、単純な話、インターネットサーバーを全面的にHTTPS化しましょう！というお話です。
　Web開発者の方々やサーバー管理者の方々に向けて、せっかくサーバーをSSL化するのであれば、できればこのあたりまでやっておけば、より安心できるのでは？と思うポイントについて提案したいと思います。

# :sunny:常時SSL化のメリット
　SSLは昔からある通信プロトコルですが、なぜそれが今になって声高に叫ばれるようになったのでしょうか。各種サイトやメディアなどでは、次のような環境の変化に対応するため、SEO対策の一環として常時SSL化した方が良いですよ、という論調が多いように思います。

- **[GoogleがHTTPSサイトを検索結果の表示順位で優遇](https://webmaster-ja.googleblog.com/2014/08/https-as-ranking-signal.html)**（Google）

- **[Yahoo!Japanが2017年3月末までに全サイトを常時SSL化、アクセス解析ツールで正確な分析ができなくなるおそれ](http://docs.yahoo.co.jp/info/aossl/)**（ヤフー）

- **[HTTP/2と組み合わせて表示を高速化できる](http://codezine.jp/article/detail/8663)**（CodeZine）

- **[ブラウザでHTTPのサイトにアクセスすると安全ではないサイトとして警告が出てしまう](https://security.googleblog.com/2016/09/moving-towards-more-secure-web.html)**（Google）

　マーケティング部門やWebコンテンツの管理者にとっては、もちろんこれらが最も大切、という場合もあると思いますが、エンジニアの見地からすればこれらの理由は少し本質的な部分からは外れていて、目を向けるべきはその背景にある**セキュリティリスクへの対応責任**だと私は思っています。

# :thinking:常時SSL化はほんとに必要なの？
1. 社会的にITインフラの整備が進み、公衆無線LANからのインターネット利用や、**オンラインで機密情報をやり取りすることが当り前**の世の中になった
2. 「Firesheep」や「sslstrip」などの登場により、さほど**スキルの高くない人でも通信の傍受や成りすましが簡単にできてしまう**ようになってしまった（もちろん**犯罪行為**なのですが・・・）

　これら2つの要因によって、WebサイトをSSL化していないということは、**自身のサイトに訪れるお客様や会員をそういった危険にさらしてしまう**ことに他なりません。
　つまりWebサイトの運営者は、自身のメリットのためはさておき、アクセスしてくださるお客様の安全を確保するため、全ての通信をSSL暗号化通信にしておくことが**サーバー管理者の責務**として求められていると考えるべきではないでしょうか。

　　　**やった方がいい :x:**
　　　**すぐにでもやらないといけない :o:**

# :helmet_with_cross:合わせて点検・対応すべきこと
　さて、本題です。サーバーのSSL化の方法については、他にいくつも詳しい記事がありますのでそれらを参照いただければと思います。ここでは、SSL化と同時に対応が可能（必要）で、インフラエンジニアとフロントエンドエンジニアが力を合わせ、よりセキュアなサーバー環境づくりをするためのポイント、またSEO対策を漏れなく行うためのノウハウを列挙しておきます。
　もちろん全て対応できれば申し分ないのですが、対応に時間がかかったり、調査だけでも大変なものもあります。中には簡単なものもありますので、できるものからだけでも取り組んでおくことをおすすめします。

* **HTTPS混在エラーを避けるHTML記述をする（localhost）**  
　混在コンテンツがある場合、そのコンテンツが盗聴・改ざんされる恐れがあるため、ブラウザで警告が表示されてしまいます。それを避けるにはページに表示する同一ホスト内のリソース（画像、CSS、JavaScript等）はすべてSSL領域から読み出す必要があり、相対パスかドメインを指定しない「/」から始まる絶対パスで記述します。

```html:html
src="../xxxx.html"
src="/yyyy.html"
src="//www.example.com/zzzz.html"
```

* **HTTPS混在エラーを避けるHTML記述をする（remotehost）**  
　画像、iframe、スクリプト、ビーコンタグ等、外部サイトのリソースを参照して利用をする場合にも必ずHTTPSプロトコルを指定しましょう。  
　※参照先がHTTPSに未対応の場合はどうしようもありませんが:worried:

```html:html
<div class="fb-like" data-href="https://developers.facebook.com/docs/plugins/" data-layout="standard" data-action="like" data-size="small" data-show-faces="true" data-share="true"></div>
```

* **Content Security Policy（CSP）の記述**  
　二重の備えとして、XSS（クロスサイトスクリプティング）やクリックジャッキングのリスクを軽減するため、JavaScript など外部から読み込むコンテンツをホワイトリストとして指定し、それ以外のコンテンツが有効にならないようにしておきましょう。

```apache:.htaccess
Header set X-Content-Security-Policy "default-src 'self'"
Header set X-WebKit-CSP "default-src 'self'"
Header set Content-Security-Policy "default-src 'self'"
```

* **検索エンジンへの最適化**
　HTTPSのコンテンツがクロールの拒絶対象となっていないか、HTTPに置き換えていないか、またコンテンツのmetaタグでnoindexが指定されていないかを確認し、HTTPSのページが正常にクロールされ、検索エンジンのインデックスへ登録されるよう記述を修正しましょう。
　またcanonical属性タグが適切に使用されているかを確認し、それまでのHTTPサイトとHTTPS化されたサイトの評価がそれぞれに分散しないようにしておきましょう。

* **サイト内検索ツール、ログ解析ツールの範囲の確認**
　サイト内検索ツールやログ解析ツールがHTTPSのページを対象としているかを確認し、必要であれば忘れずに対象に加えておきましょう。

* **適切な位置へのサイトシールの配置**
　パスワード入力欄の脇やクレジットカード番号入力欄など、ページ内の効果的な位置にシールを配置するだけで信頼性と安心感が増し、コンバージョン率が向上するそうです。シール付きのSSLサーバー証明書を使っている場合には、是非その効果を利用したいものです。
http://www.conversionvoodoo.com/blog/2012/05/proper-placement-of-your-trust-logos-will-improve-your-conversion-rate/

* **Cookieのセキュア属性付与**
　Cookieにセキュア属性をつけていない場合、HTTPS利用時に作成されたCookieがHTTP利用時には平文で送信されてしまうため、盗聴リスクが残ってしまいます。Cookie情報の漏洩を避けるため、Cookieには必ずセキュア属性をつけておきましょう。

```php:php
ini_set('session.cookie_secure', 1);
session_start();
```

* **HTTP Strict Transport Security（HSTS） Preload への対応**  
　HSTSは、ブラウザでアクセスしたドメインに対して強制的にHTTPSで通信させる機構です。RFC6797で定義され、主要なブラウザはすでに対応済みになっています。  
　条件として、別サーバで稼働しているサブドメインも含めてすべてのHTTPアクセスをHTTPSにリダイレクトして配信しており、ベースドメイン上でHSTSヘッダを送信している必要がありますので、別サーバーで稼働しているサイトも同時にSSL化する必要があります。  
　それらの対応が完了すれば、下記のページで該当のドメイン名を対象ドメインのリストに加えましょう。  
　https://hstspreload.appspot.com/

```:.htaccess
Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]
```

* **301リダイレクト**  
　検索エンジンにとってURLの異なるHTTPのサイトとHTTPSのサイトは別サイトとみなしてしまうため、安易なリダイレクト処理では結果的にサイトの評価が下がる可能性があります。それを避けるには、301リダイレクト方式でリダイレクトを行うことが必要です。  
　.htaccessに下記の記述を加えることにより、HTTPのサイトからHTTPSのサイトへリダイレクトされるようになり、サイトの評価も引き継がれます。

```apache:.htaccess
<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
</IfModule>
```

# :date:常時SSL化のスケジュール案
　新しく構築するインターネットサーバーを常時SSL化するには、先に書いた内容を標準ルール化して構築すれば良いのですが、すでに運用中のHTTPサーバーを常時SSL化するには、たいていの場合は様々なインパクトや運用上のデメリットを最小限に抑えるため、それぞれの実装やその他の留意事項への対応を順番に実施する必要があると思います。
　簡単ではありますが、以下にその一例を示しておきたいと思います。

![aossl-project.png](https://qiita-image-store.s3.amazonaws.com/0/24395/ef0f911e-c9a5-1350-6c1e-4a9391765ad6.png)

# :worried:常時SSL化のデメリット
　上記画像にも記載していますが、常時SSL化によるデメリットもあります。諦めるしかないものも多いのですが、どのタイミングでどういった問題が生じるのかは押さえておきましょう。

* SSLサーバー証明書の費用（最近は無料のものもあります）
* SNSの評価（いいね！等）がHTTPとHTTPSのサイトで分かれてしまう
* HTTPS化されていない外部サイトのビーコンやツールが利用できない
* HTTPSサイトへの通信の監査が困難になる

# :lock:使用するSSLサーバー証明書について
　通常、SSLサーバー証明書は有料です。最近は**Let's Encrypt**に代表されるような無料の証明書も登場していますが、これらは**ドメイン認証型SSLサーバー証明書（DV証明書）**と言われるもので、SSL暗号化通信については問題なく行えますが、ドメインの所有者やそのSSLサーバー証明書の取得者の実在性などは審査されていません。要するに、そのドメイン名とは全く関係のない第三者でも申請できてしまい、フィッシングサイトなどでも利用されるケースがあります。最近ではこういった事件も発生しており、DV証明書全体の信頼性が懸念されています。
　[◆ITmedia 中国の認証局が不正な証明書、主要ブラウザが無効化を通告](http://www.itmedia.co.jp/enterprise/articles/1611/02/news082.html)

　同じドメイン名であっても、サブドメイン名が違えばそれぞれ別のSSLサーバー証明書が必要になる場合が多く、有料の証明書となるとそれなりのコストがかかってしまいます。しかしやはり、法人や個人事業主などが商用で運営するサイトには、できれば厳格な審査が必要な**EV SSLサーバー証明書（EV証明書）**か、少なくとも取得者の実在が証明されている**企業認証型SSLサーバー証明書（OV証明書）**を使うべきでしょう。

# :writing_hand_tone1:まとめ
　今現在はまだ過渡期と言えますが、Googleがそうであるように、徐々にHTTPでの通信には制限や制約が加えられており、かなり近い将来、インターネット上でのHTTPでの通信は完全になくなってしまうだろうと予測しています。
　常時SSL化（この言葉自体が死語になるでしょう）が標準となり、HTTPS化されていないサイトを利用者が敬遠する時代がすぐにやってきます。そういった時期が到来し、劣等生にならないためにも、常時SSL化は、**今**、やっておくべきだと思います。


以上になります。最後までお付き合いくださり、ありがとうございました:grinning: