1. pm11op

    Posted

    pm11op
Changes in title
+Let's Encrypt で証明書を小刻みに自動更新
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,86 @@
+
+* お手軽 SSL の Let's Encrypt、便利だけど証明書の有効期限が 3ヶ月で切れるのを何とかしたい
+* 証明書の更新コマンドが用意されてるので、自動更新が可能
+* monthly の cron で月1回更新してもいいけど、2,3回連続で失敗したら終わる
+* 公式ドキュメントには下記のようにある。(公式もネットワークトラブルやサーバダウンによる失敗を懸念している)
+
+> We recommend running renewal scripts at least daily, at a random hour and minute. This gives the script many days to retry renewal in case of transient network failures or server outages.
+> [How It Works - Let's Encrypt](https://letsencrypt.org/howitworks/#writing-your-own-renewal-script)
+
+というわけで、なるべく公式の意に沿うようにやってみる
+
+## 1日1回、ランダムなタイミングで証明書を更新(そして怒られる)
+さすがに毎日はやり過ぎな気はしたけど
+
+```crontab
+0 2 * * * sleep $[($RANDOM % 175)+5]m; /path/to/letsencrypt-renew.sh >/dev/null 2>&1
+```
+※ ログは捨ててない
+
+```/path/to/letsencrypt-renew.sh
+#!/bin/bash
+SCRIPT=/usr/local/src/letsencrypt/letsencrypt-auto
+WEBROOT=/path/to/webroot
+DOMAIN=example.com
+LOG=/var/log/letsencrypt/renew.log
+
+date '+%Y-%m-%d %H:%M:%S >>>' >> $LOG
+if ! $SCRIPT certonly --webroot --webroot-path $WEBROOT -d $DOMAIN --renew-by-default >> $LOG 2>&1 ; then
+ echo ' Automated renewal failed' >> $LOG
+ exit 1
+fi
+service nginx reload
+```
+
+
+
+* ランダムと言っても日中は嫌なので、02:05 〜 05:00 の間のどこかでスクリプトが実行される
+
+何回かテストして OK ぽかったので1日待つ。
+
+### 怒られた
+1日待っても証明書が更新されてなかったのでログを見たら
+
+> so a SAN multi-domain cert having domain1.com, www.domain1.com, domain2.com, www.domain2.comis counted as 1 certificate ? but you can only renew this SAN multi-domain cert 5 times per 7 days ?
+
+7日に5回までのリミットがかかってるらしい。
+
+
+## 5回に1回の確率で証明書を更新するスクリプトを毎日実行
+スクリプトの実行自体にもリミットに引っかからない程度のランダム性をもたせてみた。
+こう修正して様子見中。
+
+```crontab
+0 2 * * * sh /path/to/letsencrypt-renew.sh >/dev/null 2>&1
+```
+※ ログは捨ててない
+
+```/path/to/letsencrypt-renew.sh
+#!/bin/bash
+SCRIPT=/usr/local/src/letsencrypt/letsencrypt-auto
+WEBROOT=/path/to/webroot
+DOMAIN=example.com
+LOG=/var/log/letsencrypt/renew.log
+
+date '+%Y-%m-%d %H:%M:%S >>>' >> $LOG
+
+# ececute 1/5
+if [ $(($RANDOM%5)) -ne 1 ]; then
+ echo ' do nothing ' >> $LOG
+ exit;
+fi
+
+echo ' sleeping... ' >> $LOG
+
+# sleep 5 - 180 min
+sleep $[($RANDOM % 175)+5]m
+
+date '+%Y-%m-%d %H:%M:%S woke up!!>>>' >> $LOG
+if ! $SCRIPT certonly --webroot --webroot-path $WEBROOT -d $DOMAIN --renew-by-default >> $LOG 2>&1 ; then
+ echo ' Automated renewal failed' >> $LOG
+ exit 1
+fi
+service nginx reload
+```
+
+\# 成功/失敗の結果を Slack とかに通知したらいいと思う