Let's encrypt運用のベストプラクティス

  • 199
    いいね
  • 0
    コメント

この記事について

Let's encryptは無料で使用できるSSLプラットフォームです。certbotコマンドを使って、簡単にSSL証明書の取得と更新ができます。

しかし、あまりに簡単で手軽すぎるためか、ネット上ではやや問題のある手順が紹介されているケースが見られました。私なりにベストと思われる手順をまとめておきますので、改善点があれば教えてください。

DNSの設定、Webサーバのセットアップ、certbotのインストールは完了しているとします。またcertbotのコマンド名はcertbot-autoで、$PATHが通っていると想定します。

証明書の取得

以下のような補助スクリプトを準備します。

letsencrypt.sh
#!/bin/sh

#証明書のドメイン(,区切りで複数のドメインも指定可能)
DOMAIN=example.com

#ドキュメントルート(上のドメインで接続可能である必要がある)
WEBROOT=/var/www/example.com/public_html

#メールアドレス(トラブル時にメールが届く)
EMAIL=info@example.com

certbot-auto certonly -m $EMAIL --agree-tos --non-interactive $* --webroot -w $WEBROOT -d $DOMAIN

証明書の取得テストは次のように行います。

sudo ./letsencrypt.sh --test-cert

本番用の証明書を取得するには次のようにします。

sudo ./letsencrypt.sh --force-renewal

新たなドメインに対する証明書が必要になるたび、このプロセスを繰り返してください。

運用のポイント

ポイント1. まずテスト用の証明書を取得する

--test-cert オプションを与えることで、テスト専用のサーバに接続します。ここで取得できる証明書は無効なものですが、certbotが正しく動作するか、ドメインの設定等が間違っていないか、まずこの段階で確認しておきましょう。

ポイント2. webrootプラグインを使う

certbot自体をWebサーバとして機能させる、standaloneプラグインもありますが、利用するケースは限られるはずです。動作確認でも、実際の運用でも、webrootプラグインを使うほうが簡単でしょう。

証明書の確認・インストール

取得した秘密鍵・証明書・中間証明書のファイルは、デフォルトでは以下のディレクトリに配置されます。

/etc/letsencrypt/live/${DOMAIN}/
  • privkey.pem 秘密鍵
  • cert.pem 証明書
  • chain.pem 中間証明書
  • fullchain.pem 証明書と中間証明書を連結したファイル

設定方法はソフトウェア次第ですが、例としてApacheをとりあげます。

バージョン2.4.7以前の場合、次のように設定します。

httpd.conf
SSLEngine on
SSLCertificateFile      /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile   /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem

バージョン2.4.8以降の場合は、SSLCertificateFile ディレクティブでfullchain.pemを参照します。

httpd.conf
SSLEngine on
SSLCertificateFile      /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile   /etc/letsencrypt/live/example.com/privkey.pem

運用のポイント

ポイント1. 常に同じパスで最新版を参照できる

これらのファイルはすべてシンボリックリンクで、それぞれ最新版の実体ファイルにリンクされています。証明書を更新しても、ファイルパスを変更する必要はありません。

実体のファイルは /etc/letsencrypt/archive/${DOMAIN} 以下に、番号付きのファイル名で保存されています。

ポイント2. fullchain.pemの使い方

fullchain.pem には、証明書と中間証明書の両方が含まれています。

#要するにこういうこと
cat cert.pem chain.pem > fullchain.pem

SSLを利用するソフトウェアの中には、中間証明書を設定する項目がないものもあります。たとえばnginx, Postfix, Dovecotなどなど。そのような場合には、このfullchain.pemを証明書ファイルとして指定します。

証明書の更新

以下のようなスクリプトを、cronで毎日〜週に1回程度の頻度で実行します1--post-hook オプションの引数は、使用しているOS/ソフトウェアに合わせて変更してください。

certbot-auto renew -q --no-self-upgrade --post-hook "service httpd reload"

運用のポイント

ポイント1. renewサブコマンドを使う

renew を実行すると、これまでに取得した全ての証明書の期限がチェックされ、30日以内に期限が切れるものを自動的に更新します。

証明書の取得時に使用したオプションは

/etc/letsencrypt/renewal/${DOMAIN}.conf

というファイルに保存されており、更新時にはこの設定が使用されます。変更が必要なら、このファイルを修正しましょう。

ポイント2. --force-renewal オプションは使用しない

--force-renewal オプションは、残り期限にかかわらず、強制的にすべての証明書を更新します。不要な負荷をかけることになるので、cronでの実行時には指定してはいけません。let's encryptの使用量制限に引っかかる可能性もあります。

ポイント3. 証明書の再読み込みには --post-hook オプションを使う

--post-hook で指定したコマンドは、証明書の更新が行われた場合にのみ、1度だけ実行されます。更新が行われなかった場合は実行されません。ここでWebサーバの再読み込み処理を実行すると良いでしょう。


  1. cronでの実行頻度については、User Guideによれば毎日〜毎週、All Instructiosによれば1日に2回が推奨。期限が近い証明書がなければ、特になにもしないので、さほど神経質になる必要はありません。