Let's EncryptのSSL証明書を使ってお手軽HTTP/2対応


最近はRails芸人というよりAWS芸人っぽくなってきた[すろっくさん](http://twitter.com/srockstyle)です。仕事でコード書くんですが、なぜかWAF使う機会ががっつりと減ってしまいましたイタタタ。

ところで無料でSSL証明書をくれる[Let's Encrypt](https://letsencrypt.org/)がオープンベータになりました。さっそくなので、これを使って自分のサイトをHTTP/2対応してみましょう！

詳しい資料はこちらの方のが便利です。

 * [HTTP/2入門](http://www.slideshare.net/asumaslv/http2-57141644)

さてやっていきます。
我が家の構成はLB <-> nginx <-> PHPですが、この場合PHPはあまりでてこないです。

## ネットワーク構成の設定を確認

Let's Encryptは証明書を取得するときに80番ポートと443番ポートを使うサーバを立ち上げます。つまり両方落ちてないとダメなわけです。Webサーバダウンさせないといけないわけですねー。

とはいえ、その直前で切れていたら元も子もないので、443と80のポートが空いているかどうかの確認はしましょう。

空いていればいいんですが、空いていないと以下のようなエラーがでます。きをつけて！

```$bash
The server could not connect to the client to verify the domain :: Failed to connect to host for DVSNI challenge, <your-domain-name> (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to host for DVSNI challenge

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: <your-domain-name>
   Type:   urn:acme:error:connection
   Detail: Failed to connect to host for DVSNI challenge
```

参考までに。

 * [Lets Encrypt Error: The server could not connect to the client to verify the domain :: Failed to connect to host for DVSNI challenge](http://eran.sandler.co.il/2015/12/31/lets-encrypt-error-the-server-could-not-connect-to-the-client-to-verify-the-domain-failed-to-connect-to-host-for-dvsni-challenge/)

あとホスト名もDNS登録しておくといいですね。しときましょう。

## プログラムのダウンロード

コードはGithubに公開されているので、それを使います。

念のため作業はrootでやっときましょう。デーモンを起動したりします。

```bash
git clone https://github.com/letsencrypt/letsencrypt
```

## 認証コマンド実行

次にcloneしてきたプログラムを実行するんですが、ここで注意。80番と443番がletsencryptのデーモンで一時的に塞がれてしまいます。一旦Webサーバを停止する必要があります。

CentOS7とかならこう。

```bash
systemctl stop nginx
```

6とか5ならこう。

```bash
/etc/init.d/nginx stop
```

おわったら次のコマンドを実行します。

```bash
cd letsencrypt
./letsencrypt-auto certonly --standalone -d <my-domain-name>
```

途中メールアドレスを入力するところがあります。入力が終わると利用規約同意してねっていう選択肢がでるので、ターミナル上でagreeeを選択してENTERキーを押してください。

これで証明書ゲットです。はや。

## nginxに組み込む

証明書がゲットできたので、次はWebサーバをHTTP/2対応しましょう。うちはフロントがnginxなので、nginxを書いていきます。

が。

nginxがHTTP/2対応したのは1.9.5以降です。バージョンを確認しないと起動に失敗＆ただのhttps通信になるので気をつけて下さい。

nginxのバージョンは以下で確認できます。

```bash
[root@myserver ~]# nginx -v
nginx version: nginx/1.6.3
```

ひくかったし1.9系ですらなかったつらい。

バージョンアップしましょう。

公式のリポジトリでmainlineを使えば最新版が入ります。

/etc/yum.repo.d/nginxを以下に変更しましょ。

```
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
```

以下のコマンドでアップグレード。

```bash
yum upgrade nginx
```

確認します。

```bash
[root@ myServer ~]# nginx -v
nginx version: nginx/1.9.10
```

なりましたね！　

nginxの設定は以下を書きます。HTTP/2化させたいサイトのserverディレクティブに以下を追記してください。

[参考にさせていただきました！](http://qiita.com/jpshadowapps/items/3da47ecaa8fbfc0c01ea)　ありがとうございます！

```nginx.conf
server {
　　・・・
　　・・・
    listen       443 ssl http2 ;
    ssl_certificate /etc/letsencrypt/live/<my-domain-name>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<my-domain-name>/privkey.pem;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_ciphers AESGCM:HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

　　・・・
　　・・・
}
```

ここで注意。もともと80番で待ち受けていたのを443に変更するので、リダイレクトが必要です。

リダイレクトは以下を記述しましょう。

```nginx.conf
server {
    listen 80;
    server_name <your-domain-name>;
    return 301 https://<your-domain-name>;
}
```


そしたら再起動です！

CentOS7とか。

```bash
systemctl restart nginx
```

6とか5とか。

```bash
/etc/init.d/nginx restart
```

## 検証

できたら検証です。

WordPressなどのCMSを使っている場合は、サイトのURLをhttpsに変更するのを忘れないように？　画像がでなくなってしまいます！

URLがhttpsになっていることを確認しましょう。Chromeでアクセスして変な警告がでなければ大丈夫です。
![スクリーンショット 2016-02-05 6.35.06.png](https://qiita-image-store.s3.amazonaws.com/0/2820/0bfe2254-bbeb-2779-b935-69f387d3fc64.png "スクリーンショット 2016-02-05 6.35.06.png")

次にChromeの開発ツールを開いて、安全性を確認します。
![スクリーンショット 2016-02-05 6.28.57.png](https://qiita-image-store.s3.amazonaws.com/0/2820/7bd068d3-18a0-e8b3-0757-c7672113642e.png "スクリーンショット 2016-02-05 6.28.57.png")

ちゃんとセキュアだよ、有効だよと出してくれます。

最後にnginxのログをみてHTTP/2になっていることを確認しましょう。

![スクリーンショット 2016-02-05 6.30.31.png](https://qiita-image-store.s3.amazonaws.com/0/2820/ed3886f6-34fb-b94c-12a9-e938359480f2.png "スクリーンショット 2016-02-05 6.30.31.png")

なってますね！！！　やった！

## 証明書の更新

さて、これで設定はできたんですが、 Let's Encryptは3ヶ月で切れてしまいます。

更新スクリプトが公式にあるので、コピペして使います。

```sh
#!/bin/sh
systemctl stop nginx
if ! <letsencryptをcloneしたパス>/letsencrypt/letsencrypt-auto certonly -tvv --standalone --keep -d <my-domain-name1>,<my-domain-name2> > /var/log/letsencrypt/renew.log 2>&1 ; then
    echo Automated renewal failed:
    cat /var/log/letsencrypt/renew.log
    exit 1
fi
systemctl start nginx
```

これをCronとかで定期的に回せばよいかと思いまーす。

## まとめ

ずっとずっとやらなきゃなーと思ってたhttps&HTTP/2対応ができて嬉しいです！

Webサービスを作ってもhttpsにできるので信頼性あがりますね！

みんなも Let's Encrypt！だよ！