Let's EncryptのSSL証明書を10秒でNGINXに導入・設定! --nginxオプションが便利

NGINXにLet's EncryptのSSL証明書を入れる時、--nginxオプションを使えば一発で完了します。簡単すぎ。

# はじめに
久々に、とあるサーバにLet's Encryptの証明書を導入しようとしたものの、手順をすっかり忘れていました。
以前自分でも手順の紹介エントリを書いた[^1]のですが、改めて確認すると少し面倒です。
(面倒といっても、証明書の発行とnginxの設定だけなんですがね・・・)

ところで、前回調べた際はマニュアルに「動かない」と明記されていたため試しても見なかったnginxプラグイン(「--nginx」オプションで有効化)を試してみたところ、証明書の取得から設定まで全てやってくれました。
冗談ではなく本当に10秒も掛からずインストールと設定まで完了しました。
非常に便利だったので、そのご紹介です。
(もっとも、マニュアルには「まだ実験的機能」と書かれているので、不安定なところが残っているのかもしれませんが)

# 動作確認環境
・ArchLinux (Linux 4.4.3)
・NGINX 1.8.1
・letsencrypt 0.4.2
・[letsencypt-nginx](https://github.com/letsencrypt/letsencrypt/tree/master/letsencrypt-nginx) 0.4.2 (プラグイン)

# 簡単なまとめ (TL;DR)

1. 検証環境から証明書取得 `letsencrypt --nginx --staging`
2. ブラウザ等で動作確認
3. 本番環境から証明書取得 `letsencrypt --nginx`

# letsencryptコマンドのインストール
ArchLinuxの場合です。

```bash
sudo pacman -S letsencrypt
sudo pacman -S letsencrypt-nginx
```

# 設定ファイルの準備 (cli.ini)
SSLサーバ証明書を発行してもらうドメイン名など、必要なパラメータをあらかじめ
/etc/letsencrypt/cli.ini
に設定します。
コマンドラインにバラメータを全部指定すると長くて煩雑なため。

*example.comをご自分のドメインに置換して下さい*

```ini:/etc/letsencrypt/cli.ini
rsa-key-size = 2048
server = https://acme-v01.api.letsencrypt.org/directory
email = admin@example.com
domains = test.example.com
text = True
webroot-path = /var/www/html
agree-tos = True
renew-by-default = True
```

# 手順

ルートで作業します。

```shell-session
% sudo -i
[root@vultr-server-01 ~]# 
```

NGINXは起動した状態のままでOKです。

```shell-session
[root@vultr-server-01 ~]# curl -sI localhost | head -3
HTTP/1.1 200 OK
Server: nginx/1.8.1
Date: Sun, 06 Mar 2016 20:35:37 GMT
```

## (Let's Encryptの)テスト環境からテスト用証明書取得
```bash
letsencrypt --nginx --staging
```

ログ
(途中、入力が求められます。この場合では1を入力しました)

```shell-session
[root@vultr-server-01 ~]# letsencrypt --nginx --staging

Please choose whether HTTPS access is required or optional.
-------------------------------------------------------------------------------
1: Easy - Allow both HTTP and HTTPS access to these sites
2: Secure - Make all requests redirect to secure HTTPS access
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1

-------------------------------------------------------------------------------
Congratulations! You have successfully enabled https://test.example.com
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=test.example.com
-------------------------------------------------------------------------------

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/test.example.com/fullchain.pem. Your cert
   will expire on 2016-06-04. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
```

## 動作確認
ブラウザで今設定中のNGINXにアクセスすると、証明書エラーとなりますが、これはテスト用の証明書(Happy hacker fake CA)が設定されているためで問題ありません。
発行者がLet's Encryptであること、有効期限の正しさ(今から3ヵ月間)などを確認しましょう。
意図したとおり設定されている事が確認できたら、(Let's Encryptの)本番環境から証明書を取得します。

## (Let's Encryptの) 本番環境から証明書取得
```bash
# --staging を外すだけ
letsencrypt --nginx
```

ログ
(途中、入力が求められます。この場合では1を入力しました)
今回は重要なE-メールも送られているとのことなので、そちらも別途確認しましょう。

```shell-session
[root@vultr-server-01 ~]# letsencrypt --nginx

Please choose whether HTTPS access is required or optional.
-------------------------------------------------------------------------------
1: Easy - Allow both HTTP and HTTPS access to these sites
2: Secure - Make all requests redirect to secure HTTPS access
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1

-------------------------------------------------------------------------------
Your existing certificate has been successfully renewed, and the new certificate
has been installed.

The new certificate covers the following domains: https://test.example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=test.example.com
-------------------------------------------------------------------------------

IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to admin@example.com.
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/test.example.com/fullchain.pem. Your cert
   will expire on 2016-06-04. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
```

## 通常と違うパスにNGINXをインストールしている場合
nginxが既知のパスにない場合には、以下のオプションを使えば良いとのこと。

```bash
 --nginx-server-root NGINXのサーバルート(nginx.confがあるディレクトリ)
 --nginx-ctl NGINXの実行ファイルのパス
```

上記の説明を含んだ詳細なヘルプは、`letsencrypt -h all`で表示されます。

(ちなみに、/opt/openresty 以下にインストールしたOpenRestyで試してみたのですが、残念ながら失敗しました。
mime.typesのフォーマットが違うというエラーだったので、本質的ではない気がします)

## nginx.confに自動で追加された内容
```nginx:/etc/nginx/nginx.conf
http {
    server {
        server_name test.example.com;
        listen 443 ssl;
        ssl_certificate /etc/letsencrypt/live/test.example.com-0001/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/test.example.com-0001/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_trusted_certificate /etc/letsencrypt/live/test.example.com-0001/chain.pem;
        ssl_stapling on;
        ssl_stapling_verify on;
    }
    # ...以下略...
}
```
SSL関連の設定は別のファイルに切り分けられ、インクルードされています。内容は以下の通りでした。

```config:/etc/letsencrypt/options-ssl-nginx.conf
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
# Using list of ciphers from "Bulletproof SSL and TLS"
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA";
```

# おわりに
Let's Encryptが発行した証明書は500,000を越えたそうです。コマンドのバージョンも、2016/3/8時点でv0.4.2まで上がっており、使い方も少し変化がありました。
気になる部分だけ拾ってみました。

* letsencrypt-0.4.0以降、`letsencrypt-auto`は非推奨になり、`letsencrypt`コマンドが推奨に
* letsencrypt-0.4.0以降、ECDSA形式のSSL証明書が発行可能に (参考: [Let's Encrypt の証明書をECDSA(ECC: 楕円曲線暗号)で作成する](http://qiita.com/TsutomuNakamura/items/e2e7be7c1f4d1638454d))
* 証明書の更新は `letsencrypt renew`で。ローカルに存在する30日未満で期限切れを迎える証明書を全て更新。
* [サードパーティプラグイン](https://github.com/letsencrypt/letsencrypt/wiki/Plugins)が続々登場。pleskプラグインが便利そう。

# 参考
- [Let's Encrypt User Guide](http://letsencrypt.readthedocs.org/en/latest/using.html)

[^1]: [Let's Encryptから無料・安全なSSL証明書を取得してNginxに設定するまで](http://qiita.com/dseg/items/908c1b8aab19a5b26d92)