[Webarena Indigo] cronによる定時実行でLet’s Encryptを自動更新(Slack通知付き)
Let’s Encryptの証明書更新を怠ってしまった場合
Let’s Encryptは無料でサイトをSSL化できるのですが、3カ月ごとに証明書を更新する必要があります。
それを怠ればERR_CERT_DATE_INVALIDになってしまい、訪れたユーザのブラウザには「この接続ではプライバシーが保護されません。」という過激な表示がされてしまいます。
こんなのを見せられたら、まぁページを開くことはしないですね。

自動更新をTODOにいれて、定期的に更新できる豆な人は上記のような事態になることはないと思うのですが、それでも忘れてしまうことはあると思います。
環境周りの情報
早速構築していきます。
最初に、今回のジョブを仕込む環境についてです。
- Webarena Indigo
- 月額380円でVPS環境が利用できる、NTT系列のサービス
- めっちゃお得。詳しくは以下をご覧ください。
- WebARENA(VPSクラウド)
- OSはいくつか選べますが、Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-106-generic x86_64)を使ってます。
- Nginx
- 証明書を利用しているNginxはDocker上で動いてます
- そのため、証明書の更新後にコンテナの再起動をします
- Slack
- アカウント作成済み
- webhookを取得している
- してない場合は、以下より作成する
- https://mikankui.slack.com/apps/new/A0F7XDUAZ-incoming-webhooks
- Certbot
- 私は環境を汚したくなかったためDockerを利用しています
- Dockerを使ったCertbotの証明書更新は下記の記事を参照ください
- WebARENAの使い方 – (ドメイン更新:Let’s Encrypt でSSL化)
- ただ、OSに直接インストールしてもOKです
Shellスクリプトの作成
cronで定期的に実行したい作業をshellスクリプトとして用意します。
全部で3つのスクリプトを作成しています。
- cerbot-renew.sh
- メイン処理
- 証明書の現状をチェック
- 証明書の更新処理を実行
- 結果をslackへ通知
- メイン処理
- docker-cerbot-renew.sh
- 証明書の更新処理(Dockerコマンドで実行)
- notifyMaitokuSlack.sh
- slackへの通知処理
証明書更新のメイン処理(cronで定期実行するshell)
ポイントですが、
certbotで証明書の更新処理(docker-cerbot-renew.sh)を実行する以下のコマンドです。
printf '2\n' | sudo sh /home/ubuntu/shell/docker-cerbot-renew.sh
既に証明書が存在する場合、本当に更新するか/処理をやめるか聞かれ、Shellが入力待ちとなります。
What would you like to do? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: Keep the existing certificate for now 2: Renew & replace the cert (may be subject to CA rate limits) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
![wuulv_l yuu 10 uU:
l: Keep the existing certificate for now
. Renew & replace the cert (may be subject to CA rate I imits)
elect the appropr iate nther (1-2] then [enter] (press •c • to cancel):
0
ITCRTÅNT NOTES:
- Congratulations! Your certif icate and chain have been saved at:
/etc/letsencrypt/l ive/r
'/ful Icha in.pem
Your key fi le has been saved at:
/etc/letsencrypt/l ive/r
/pr ivkey.pem
Your cert will expire on 2021-04-02. To obtain a new or tweaked
version of this certif icate in the future, sinply run certbot
again. TO non-interactively renew Of your certif icates. run
-certbot renew-
- If you like Certbot, please consider supporting our work by:
Renewing an existing certificate for
Donating to ISRG / Let's Encrypt:
Donating to EFF:
https://letsencrypt.org/donate
ht tps://eff .org/donate-le](https://tech.shiroshika.com/wp-content/uploads/2021/01/image-13.png)
そのため
printf '2\n' |
によって、証明書の更新を行う処理を続行しています。
$ cat shell/cerbot-renew.sh
#!/bin/sh
DATETIME=`date +%Y%m%d_%H%M%S_%3N`
echo "--------------------------------------"
echo "[start]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
echo $DATETIME
echo "--------------------------------------"
#check
docker run -i --rm \
--name certbot \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
certbot/certbot certificates
#update
printf '2\n' | sudo sh /home/ubuntu/shell/docker-cerbot-renew.sh
sudo sh /home/ubuntu/shell/notifyMaitokuSlack.sh
cd /home/ubuntu/git/maitokuapi/
docker-compose restart
DATETIME=`date +%Y%m%d_%H%M%S_%3N`
echo "--------------------------------------"
echo "[ end ]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo $DATETIME
echo "--------------------------------------"
証明書の更新コマンド(私の環境ではDockerを使って実行)
更新処理の引数のポイントとしては、
-d :自身サービスのドメイン名です。(google.comみたいな)
-m :メールアドレスです。
$ cat shell/docker-cerbot-renew.sh
#!/bin/sh
docker run -i --rm \
--name certbot \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
certbot/certbot certonly \
--manual \
-d *********** \
-m *********@gmail.com \
--agree-tos \
--manual-public-ip-logging-ok \
--preferred-challenges dns-01 \
--server https://acme-v02.api.letsencrypt.org/directory
Slackへの通知処理
通知するURLをSLACK_WEBHOOK_API_URLに設定します。
$ cat shell/notifyMaitokuSlack.sh
#!/usr/bin/env bash
# set here your Webhook URL
SLACK_WEBHOOK_API_URL='https://hooks.slack.com/services/*****/****/*****'
MSG=" CERBOT DONE "
JSON="{ \"text\": \"$MSG\" }"
RES=`curl -s -X POST -H 'Content-Type: application/json' -d "$JSON" $SLACK_WEBHOOK_API_URL`
echo $RES
実行結果
上記のスクリプトを実行した結果が以下になります。
--------------------------------------
[start]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
20210102_120501_798
--------------------------------------
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
Certificate Name: *************
Serial Number: ********************************************
Key Type: RSA
Domains: *************
Expiry Date: 2021-04-02 08:38:20+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/*************/fullchain.pem
Private Key Path: /etc/letsencrypt/live/*************/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Use of --manual-public-ip-logging-ok is deprecated.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Use of --manual-public-ip-logging-ok is deprecated.
Cert not yet due for renewal
You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/*************.conf)
What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Keep the existing certificate for now
2: Renew & replace the cert (may be subject to CA rate limits)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): Renewing an existing certificate for *************
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/*************/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/*************/privkey.pem
Your cert will expire on 2021-04-02. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
ok
Restarting nginx ... done
Restarting django ... done
Restarting postgres ... done --------------------------------------
[ end ]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
20210102_120523_572
--------------------------------------
cronへの登録
Linuxでの定時実行はcronを使います。
cronへの登録
実行した結果を残したいため、
cerbot-renew.log 2>&1
でログを出力しています。
cat /etc/cron.d/cron_cerbot
# /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command */2 * * * * sudo sh /home/ubuntu/shell/cerbot-renew.sh >> cerbot-renew.log 2>&1
cronに登録できたか確認
$ crontab -l
を実行することで、登録できているか確認できます。
以下は実行結果です。
0 3 1 * * sudo sh /home/ubuntu/shell/cerbot-renew.sh >> /home/ubuntu/shell/cerbot-renew.log 2>&1

実行した結果はslackへ通知されます。

まとめ
以上が、Indigo でcronを利用した定時実行により、Let’s Encryptを自動更新し、Slackに通知する手順でした。
これで安心。