Let's Encrypt で証明書を取得した時の手順備忘録

# はじめに
Let's encrypt がBeta リリースされ、ユーザ登録無しで誰でも無料のSSL/TLS 証明書を作成できるようになりました。
ここではLet's encrypt で証明書を発行する手順について、自分が作業をした時の手順を備忘録として残しておこうと思います。

# 事前準備等 
今回はFedora 23 上でLet's Encrypt の証明書を発行する手順について説明していきます。
今回の手順では割愛しますが、Let's encrypt で証明書を発行するために、事前にドメインを取得しDNS から名前解決(A/AAAA or CNAME)できるように設定をしておいてください。
今回証明書を発行する環境では既にApache がインストールされており、後術する`webroot` オプションを使用して証明書を取得していきます。

# letsencrypt クライアントの取得 
Git からリポジトリをclone してLet's Encrypt のクライアントを取得します。


```text:Let'sEncryptクライアントの取得
# git clone https://github.com/letsencrypt/letsencrypt
# cd letsencrypt
```


clone ができたら、コマンドを実行してみます。この時に足りない依存モジュールがあった場合は自動的にインストールされます。

```text:letsencryptコマンドの実行
# ./letsencrypt-auto --help all
```


# letsencrypt ドメイン認証をするためのオプション 
letsencrypt がドメイン認証を行うための方法として、以下のオプションから選択することができます。


* 証明書を発行するためのオプション
<table><tbody>
  <tr>
    <th> オプション</th>
    <th> 説明</th>
  </tr>
  <tr>
    <td> standalone</td>
    <td> シンプルなWeb サーバを起動し、ドメインを認証する方法。port 80、443 が開いていること</td>
  </tr>
  <tr>
    <td> webroot</td>
    <td> 既に稼働しているWeb サーバのwebroot ディレクトリに認証用のファイルを設置して認証を行う方法</td>
  </tr>
  <tr>
    <td> apache</td>
    <td> Apache を使用して証明書を取得、インストールまで行う</td>
  </tr>
  <tr>
    <td> nginx</td>
    <td> nginx を使用して証明書を取得、インストールまで行う</td>
  </tr>
</tbody></table>

# letsencrypt-auto コマンドのstandalone プラグインで証明書を取得する(説明のみ) 
※今回はこの方法は使いません。説明のみです
letsencrypt のwrapper スクリプトであるlestyencrypt-auto を使って証明書を取得していきます。
letsencrypt-auto を使用するletsencrypt が必要に応じてアップデートされ、またOS で必要な依存パッケージも自動でインストールされます。

standalone オプションで証明書を取得する場合、`certonly` オプションと`--standalone` オプションを使用します。
このプラグインはport 80 もしくはport 443 を使用するのでコマンドを実行する前に既に実行されているWeb サーバがある場合はそれを一旦停止します。


```text:例:httpdを事前に停止する
# systemctl stop httpd
```


standalone プラグインを使うときに、port 80 とport 443 のどちらを使うかは下記の2 つのオプションを使い分けます。


```text:port80を使いたい場合
... --standalone-supported-challenges http-01
```



```text:port443を使いたい場合
... --standalone-supported-challenges tls-sni-01
```


# letsencrypt-auto コマンドのwebroot プラグインで証明書を取得する(説明のみ) 
※後ほどこの方法で実際に証明書をインストールしていきます。
もし、あなたの環境で既にWeb Server が起動しているのであれば、それを利用して証明書を取得することができます。
それを利用するには、webroot プラグインに`certonly`, `--webroot` オプションを追加して実行します。
また、Web サーバの公開ディレクトリを指定するときに`--webroot-path` もしくは`-w` オプションを使って指定することができます。


```text:webrootプラグインを使用して証明書を取得する例
# ./letsencrypt-auto certonly --webroot -w /var/www/html -d foo.example.com -d www.foo.example.com
```


## 一度に複数のドメインと複数の公開ディレクトリを使用して証明書を取得する方法 
例えば、www.foo.example.com は/var/www/html ディレクトリを公開ディレクトリとして使っていて、www.bar.example.com は/var/www/html2 ディレクトリを公開ディレクトリとして使っている場合、コマンド一発で両方の証明書を取得するには、以下のようにコマンドを実行します。


```text:webrootプラグインで複数のドメイン、複数の公開ディレクトリを使う場合
# ./letsencrypt-auto certonly --webroot -w /var/www/html -d www.foo.example.com -w /var/www/html2 -d www.bar.example.com
```


# 実際に証明書を取得する 
それでは、letsencrypt コマンドを実行して証明書を取得してみましょう。
今回の環境では既にApache が起動していて、ドキュメントルートとして`/var/www/html` が指定されているものとします。
ここでは、証明書を取得するときにメールアドレスを指定していますが、このメールアドレスは、秘密鍵を紛失した時にリカバリするために必要となるので、もしメールサーバがまだ用意できていなくてもメールアドレスを指定しておくことを推奨します。
たとえ今はメールサーバが存在しなくても、秘密鍵をなくしたときには臨時でメールサーバを構築してメールを受信できるようなるためです。


```text:letsencrypt-autoコマンドで証明書を取得する
# ./letsencrypt-auto certonly --webroot --agree-tos -w /var/www/html -d foo.example.com -d www.foo.example.com -m taro@foo.example.com
```


処理が進み、以下のようなメッセージが出力されれば証明書の取得は成功です。

```text:正常終了メッセージ
IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to taro@foo.example.com.
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/foo.example.com/fullchain.pem. Your cert will
   expire on YYYY-MM-DD. 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
```


# 証明書ファイルの確認 
取得した証明書と作成された秘密鍵は`/etc/letsencrypt/live/$domain` 配下のディレクトリに格納されます。
証明書は`/etc/letsencrypt/live/$domain/fullchain.pem`、秘密鍵は`/etc/letsencrypt/live/$domain/privkey.pem` になります。

`openssl` コマンドを使って証明書の内容を確認するには、以下のようにコマンドを実行します。

```text:opensslコマンドで証明書の内容を確認する
# openssl x509 -text -noout -in /etc/letsencrypt/live/foo.example.com/fullchain.pem
```


必要に応じてあなたのapache やnginx のSSL/TLS 設定を修正し、本証明書を使うように設定してください。
設定方法については割愛します。

# 必要なデータのバックアップについて 
秘密鍵や証明書情報は`/etc/letsencrypt` ディレクトリ配下に保存されるので、このディレクトリをバックアップするようにしてください。
このディレクトリには秘密鍵情報も含まれるので、データが外部に漏れないように保管するようにしてください。

# 証明書の自動更新 
Let's encrypt の証明書はデフォルトで有効期限が3ヶ月となっているので、自動更新するように設定しておくことを推奨します。
証明書を自動更新する場合は`--renew-by-default` オプションを使います。


```text:更新コマンドの例
# ./letsencrypt-auto certonly --webroot --agree-tos -w /var/www/html -d foo.example.com -d www.foo.example.com --renew-by-default
```


これを適宜cron 等で定期実行されるように定義を追加してください。


```text:crontab設定例(毎月2日の2時0分に更新する例)
0 2 2 * * /path/to/letsencrypt-auto certonly --webroot --agree-tos -w /var/www/html -d foo.example.com -d www.foo.example.com --renew-by-default && systemctl reload httpd
```


# Too many certificates already issued for: <Your Domain> 
短い期間で何度も証明書の発行、更新を行おうとすると下記のエラーが発生します。
下記エラーが発生してしまった場合は、しばらく時間をおいてから再度実行するようにしてください。


```text:Toomanycertificatesalreadyissued
There were too many requests of a given type :: Error creating new cert :: Too many certificates already issued for: <Your Domain>
```

# 参考
<dl>
  <dt> Let's Encrypt で手軽に HTTPS サーバを設定する</dt>
  <dd> http://qiita.com/ww24/items/9fa19594b4e3a8eb9b6f</dd>
</dl>

<dl>
  <dt> Let's Encrypt Documentation</dt>
  <dd> https://letsencrypt.readthedocs.org/en/latest/index.html</dd>
</dl>

<dl>
  <dt> Howto: easy cert generation and renewal with nginx</dt>
  <dd> https://community.letsencrypt.org/t/howto-easy-cert-generation-and-renewal-with-nginx/3491/12</dd>
</dl>