Let's Encryptの証明書更新コマンドは、月1回実行ではダメ
TL;DR
- Let's Encryptが発行するSSL証明書の有効期間は90日
- ただし時計のずれを考慮して発行(更新)手続きの1時間前を"issue date"として発行される(つまり有効期間は発行時点からだと90*24-1時間)
- なので、cronで「毎月x日」の設定で月に1回更新コマンドを実行している場合、暦によっては更新が間に合わず失効する可能性がある
深く考えずに月に1回更新コマンドを実行していたら、危うく失効しかけたのでメモ。
業務上の都合で、(クラウドではなく)自前のサーバにNginxをインストールして、いくつかのWebサービスをホスティングしています。
SSL証明書はLet's Encryptから取得し、HTTPSのサービスをしています。
そして、毎月1日のAM7時に証明書の更新コマンド(certbot-auto renew)が作動するようにcronを設定していました。
このコマンドは、有効期限が30日未満(less than 30 days)であればその証明書を更新する、という動作をします。
例えば1月1日のAM7時に取得された証明書がありました。
ファイルの生成日時を確認すると、1月1日の7:06です。
ブラウザでこの証明書の有効期限を確認すると、4月1日の6:06です。
今後のcronの作動タイミングは、
2月1日AM7時
3月1日AM7時
4月1日AM7時
・・・
ということになりますが、
2月1日AM7時・・・証明書の有効期限まで30日以上あるので更新かからず
3月1日AM7時・・・証明書の有効期限まで30日以上あるので更新かからず(3月は31日まである!)
4月1日AM6時6分・・・証明書失効(!)
(約1時間の証明書期限切れ状態)
4月1日AM7時・・・ここでやっと更新がかかる
約1時間とはいえ、これでは証明書の更新が間に合っていません。
ここで、証明書の有効期限は4月1日の7:06ではないのか、という疑問がわいたのですが、
ブラウザで証明書の詳細を見ると、1月1日の6:06に有効になって、4月1日の6:06に無効になる、と表示されます。
なぜ1時間ずれているのか。
同じ疑問を持った人がいるようで、Let's Encryptのコミュニティに質問と回答がありました。
Certificate Not Valid Before dated 1 hour prior to generation - Help - Let's Encrypt Community Support
回答者の中にLet's Encryptのエンジニアさんもいますが、時計のずれを許容できるように、という理由だそうです。
結論
月に2回とか25日に1回とかの設定で更新コマンドを実行するのが安全。
蛇足な補足
実は何度か「あと20日で失効しますよ」という警告のメールが届いて、不思議に思いつつも「とりあえず」で手動で更新したことがありました。月に2回更新コマンドを実行するように変更してからはそういう「不思議な」事態は起こっていません。