Let's Encryptを使う

Let's Encrypt

SSL証明書は面倒。一つ一つの作業はそれほどでもないけど運用する証明書数が増えてくるとそれなりに煩わしくなる。

一般的なSSL証明書の取得から運用
  1. 証明書の取り扱い会社に登録する
  2. ドメインの所有確認を行う
  3. CSRを作成する
  4. 証明書のチェーンを作成する
  5. サーバの設定と証明書の配置
  6. 動作確認
  7. 証明書の期限切れを気にする
  8. 更新(3,4,5,6)

これらはLet's Encryptの利用でほとんど自動になる。自動になるのはLet's EncryptによってというよりACMEの仕組みによるという方が正しいか。
とりあえず、やらなきゃならないのはLet's Encryptを利用するためのクライアントのインストールと上の5,6番くらい。

ACMEクライアントのインストール

今回はPython用クライアントのpy-certbotをインストールする。security/py-certbotは2016年6月下旬まではsecurity/py-letsencryptだったもの。他にFreeBSDのports, pkg用にはsecurity/letsencrypt.sh (bash用)やsecurity/letskencrypt (Cプログラム)もある。

# cd /usr/ports/security/py-certbot
# make install clean

スクリプトのフロントエンドは/usr/local/bin/certbotに、証明書など利用者にとって重要なものは/usr/local/etc/letsencrypt置かれる。

証明書の発行

Let's Encryptへの登録は不要。いきなりcertbotでコマンドを打つだけ。

ユーザーガイド

最も手抜きでFQDNだけ指定
# certbot certonly -d host.example.com

幾つか質問されるが間違えないように入力するのはウェブルート。これは発行する証明書のウェブサイトのドキュメントルートのPathなので/usr/local/www/host_exampleなど。
これでhost.example.comの証明書が取得できる。

ウェブルート(ドキュメントルート)のPath付きで実行
# certbot certonly -d host.example.com -w /usr/local/www/host_example

正しく動作していれば証明書は/usr/local/etc/letsencrypt/live/host.example.com下に置かれている筈。

ウェブサーバの設定

Nginxで使用するなら
1
2
3
ssl_certificate /usr/local/etc/letsencrypt/live/host.example.com/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/host.example.com/privkey.pem;
ssl_trusted_certificate /usr/local/etc/letsencrypt/live/host.example.com/chain.pem;

Nginxのssl_certificateはEE証明書と中間CA証明書が入ったものを指定するのでfullchain.pemを指定。ssl_trusted_certificateは必須ではない。←OCSP Staplingを有効にする場合に設定する。

Apache2.4で使用するなら
1
2
3
SSLCertificateFile "/usr/local/etc/letsencrypt/live/host.example.com/cert.pem"
SSLCertificateKeyFile "/usr/local/etc/letsencrypt/live/host.example.com/privkey.pem"
SSLCertificateChainFile "/usr/local/etc/letsencrypt/live/host.example.com/chain.pem"

ApacheではSSLCertificateFileでEE証明書を指定、SSLCertificateChainFileで中間CA証明書を指定する。

証明書の自動更新

Let's Encryptの証明書の期限は90日(約3ヶ月)となっている。こんな有効期間の短いものが普通の更新手順だったら冗談じゃないけど、もちろん自動更新できるのでcronに仕掛けるだけ。ただし、更新可能期間は期限切れ直前の30日(約1ヶ月)だけ。cronジョブは15日に1度程度実行すれば更新可能期限の30日以内に間違いなく1回はcronジョブが走る筈。更新可能期間外に実行すると単に弾かれるだけ。

/etc/crontabにNginx用またはApache2.4用のどちらか1行追記
1
2
3
4
5
#Nginx
50 4 2,16 * * root /usr/local/bin/certbot renew --quiet && /usr/local/etc/rc.d/nginx reload

#Apache24
50 4 2,16 * * root /usr/local/bin/certbot renew --quiet && /usr/local/etc/rc.d/apache24 reload

毎月2日と16日の朝4:50に走る

2016年7月24日現在はcertbotではECDSAの証明書の発行はできないみたい(Let's EncryptでECDSAの証明書の発行はできる)。リクエストは出ているようなのでそのうちに対応するかも。
仕組みが仕組みなのでHPKPとは相性悪くてcertbotを使うなら諦めた方が良さそう。まぁHPKP自体が筋悪なのであまり使おうぜと言えないものだけど。

2018年3月1日追記:
Let’s EncryptでECDSAな証明書に書いたけど、CSRを固定にする方法ならHPKPのpinが変わらないのでHPKPもイケる。CSRを作るところまではApacheでSSL (その勘所)を参照。(CSR/証明書作成はApache関係なく共通)

関連記事: