IDCFクラウドを用いてざっくりとSSLに対応させる


この記事は、IDCFクラウド Advent Calendar 19日目の内容です。普通に2日前に出てきましたが、こっちが本来記述する予定日でしたが、気にしないことにしましょう。

先日構築した、[IDCFクラウドでざっくりとa-blog cmsを構築する](http://qiita.com/nasa114/items/ef73a7b80984fc092de9)記事の環境をベースにします。（LAMP）

## 全面SSLのメリット

全面SSLをすることによるメリットを記載すると、以下の点です。

* GoogleからのSEO評価があがるかもしれない
* どうせお金かけるのであれば、全部対応させたほうがリダイレクト処理が楽
* サイトの改ざんが難しくなる
* 全体が暗号化されることによって、プライバシーが高まる。

しかし、SSL証明書を導入する時に迷う点が&#8220; **お金が予想以上にかかる** &#8221;という点であると思います。さくらのSSLでは年額1,500円（税抜, RapidSSL）ネットオウルが提供するSSL BOXであっても、年額990円（税抜き, CoreSSL）からとなっています。

1つのサイトを管理しているのであれば、金額をかけてちゃんとしたのを取得したほうが良いですが、法人でなければ無料のでも良いとは思います。

無償でSSL証明書を発行する事業者を以下に挙げます。

* StartSSL（少し前話題になった事業者。更新が超絶面倒）
* WoSign（よくわからない）
* Let's Encrypt（2015年12月現在ではBeta版。コマンドラインから取得・更新が可能）

どれを使うかもう一択しかないですね！Let's Encryptを用います。今までStartSSLで難なく更新出来ている人は別にそれでも良いと思います。しかし、私は少しでも手間を省きたいと思うので選びました。

### Let's Encryptとは？

Let's Encryptとは、無料で自動的にSSL証明書を発行するプロジェクトです。従来のSSL証明書と比較して、異なる点は以下のとおり。

* **SSL証明書の更新スパンが短い**（3ヶ月）
* GUI操作なしに更新できる

他にも多くあるかもしれませんが、とりあえずこれだけ覚えていれば大丈夫でしょう。

無料で発行できますし、ブラウザの対応状況も良いです。まだベータ版ではありますが、正式版になっても同じだとは思います。

## SSL証明書を導入する

認証局はLet's Encryptを利用するので、サーバー側で以下のようにします。

```
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto
```

`./letsencrypt-auto`を実行する前に、EPELレポジトリが入っているか確認したほうが良いですが、続きなので割愛。（`yum install epel-release`でインストールできます）

しばらく待っていると、以下の様なメッセージが出てきます。

```
Creating virtual environment...
Updating letsencrypt and virtual environment dependencies.......
Running with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt
No installers are available on your OS yet; try running "letsencrypt-auto certonly" to get a cert you can install manually
```

このようなメッセージが出れば、成功しています。実際に証明書を取得するためには、以下のコマンドで取得します。

```bash
./letsencrypt-auto certonly --webroot -w /var/www/html -d ac2015.arealv.net
```

`-w`の後ろはディレクトリ、 `-d`はドメイン名です。なので、wwwありなしどちらとも取得する場合は以下のようになります。（以下の例ではwwwありが先ですが、wwwなしが先でも問題ない）

```bash
./letsencrypt-auto certonly --webroot -w /var/www/html -d www.example.com -d example.com
```

更新を手動でするのは面倒なので、自動化してしまいます。

```bash
crontab -e
00 05 01 * * /usr/local/letsencrypt/letsencrypt-auto certonly --webroot -w /var/www/html -d www.example.com -d example.com --renew-by-default && /bin/systemctl reload httpd
```

この設定だと、毎月1日の朝5時に更新するという設定になっています。

### SSL証明書をApacheに組み込む

Apacheに組み込む方法は難しくなく、`mod_ssl`を導入していれば簡単に行うことができます。

```/etc/httpd/conf.d/99-exvhost.conf
<VirtualHost *:443>
   DocumentRoot /var/www/html/
   ServerName www.example.com
   SSLEngine on
   SSLProtocol all -SSLv2 -SSLv3
   SSLCipherSuite "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
   SSLCertificateFile /etc/letsencrypt/live/www.example.com/cert.pem
   SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
   SSLCertificateChainFile /etc/letsencrypt/live/www.example.com/chain.pem
   Header set Strict-Transport-Security "max-age=31536000; preload"
   SSLHonorCipherOrder  on
</VirtualHost>
```

上から解説すると、

* ドキュメントルート（ウェブサイトを公開するディレクトリ）
* ドメイン名
* SSLの有効化
* SSLの暗号化の設定
* SSLの証明書ファイルのパス
* HSTSの設定（本来ならサブドメインなども〜と言われそうですが、割愛）
* サーバーサイドでSSL暗号化の指定

という感じになっています。設定はMozillaのドキュメントを一部参考にしています。


## 参考

* [User Guide — Let's Encrypt 0.2.0.dev0 documentation](https://letsencrypt.readthedocs.org/en/latest/using.html#installation)
* [Let’s Encrypt サーバー証明書の取得と自動更新設定メモ | あぱーブログ](https://blog.apar.jp/linux/3619/)
* [Security/Server Side TLS - MozillaWiki](https://wiki.mozilla.org/Security/Server_Side_TLS)