Freenom ドメイン・Let's Encrypt 証明書の有効期限を確認・通知する仕組みを作った
最近、いくつかのサイトで Freenom で独自ドメインを取ったり、Let's Encrypt で証明書を取って HTTPS 化したりしている。
- GCE
- https://neos21-gce.ga/
- CentOS + Apache → Let's Encrypt を手動設定
- OCI 1
- https://neos21-oci.cf/
- Oracle Linux + nginx → Let's Encrypt を手動設定
- OCI 2
- https://neos21-oci.ml
- Ubuntu + nginx → Let's Encrypt を手動設定
- Neo's World
- https://neos21.tk/
- XREA の無料 SSL を使っているので、このサイトだけは証明書のメンテナンスが不要
Freenom のドメインは12ヶ月ごとに更新手続きを行わないといけないのだが、Freenom API は通常ユーザは使えないらしく、手作業が必要になるので、この気付きを得たい。
上3つの Always Free IaaS で動かしているサイトは、cron で certbot の更新処理を定義して毎月動かしているが、ちゃんと証明書が更新できているか一応チェックしておきたいなーと思った。
そんなワケで、ドメインと証明書の有効期限をチェックして Slack 通知する仕組みを作り込むことにする。
証明書の更新状況を JSON ファイルに出力する
まずはサイトごとに、証明書の更新状況を JSON ファイルに出力する仕組みを作る。
cron で毎月証明書を更新している処理の最後に、シェルスクリプトを実行する設定を入れる。
$ crontab -l
00 03 01 * * /root/certbot/certbot-auto renew && systemctl restart nginx && /root/certbot/update-status.sh
スクリプトの内容は以下のとおり。
/root/certbot/update-status.sh
#!/bin/bash
cert_renew_date="$(date '+%Y-%m-%d')"
cert_expiry_date="$(/root/certbot/certbot-auto certificates 2>&1 | grep 'Expiry Date' | sed 's/^.*Date\: //' | sed 's/ .*$//')"
cat <<EOL > /var/www/html/status.json
{
"global_ip" : "140.238.56.203",
"domain_name" : "neos21-oci.cf",
"domain_registration_date": "2020-08-22",
"domain_expiry_date" : "2021-08-22",
"cert_renew_date" : "${cert_renew_date}",
"cert_expiry_date" : "${cert_expiry_date}"
}
EOL
echo 'Update Status Finished'
Global IP とドメイン名はベタ書き。
ドメインの取得日、有効期限日もベタ書き。Freenom API が使えないので仕方ない。1年に1回手動で更新した時に、ココの内容を手で書き換える運用とする。
証明書の更新日は処理した日付、有効期限日は certbot
から泥臭く取得している。
このような JSON を組み立てて、/var/www/html/
配下に書き込んでいる。すなわち、
という URL で、ココで組み立てた JSON ファイルにアクセスできるようにするワケだ。
このようなスクリプトと cron 定義を、IaaS の3サイトでそれぞれ設定しておく。
XREA に関しては証明書更新が要らないので、次のようなベタ書きの JSON ファイルだけをただ置いておく。
{
"global_ip" : "neo.s21.xrea.com",
"domain_name" : "neos21.tk",
"domain_registration_date": "2020-08-22",
"domain_expiry_date" : "2021-08-22",
"cert_renew_date" : "-",
"cert_expiry_date" : "-"
}
status.json
を収集しヘルスチェックするスクリプトを組む
4つのサイトのルート直下に status.json
が配備され、ドメインの有効期限や証明書の有効期限が確認できるようになった。
続いてはこれらを収集してヘルスチェックし、よき感じにステータス状況を組み上げるスクリプトを書く。
ということで、ステータスチェック用の GitHub リポジトリを作った。
実処理は以下の2つ。
- site-status/check-status.yaml at master · Neos21/site-status · GitHub
- GitHub Actions として、毎日朝4時に以下のスクリプトを実行する
- 以下のスクリプトが書き換えた
README.md
をgit commit
する処理までが入っている
- site-status/check-status.js at master · Neos21/site-status · GitHub
- 各サイトの
status.json
を収集し、有効期限日をチェックする - 確認した結果をリポジトリ直下の
README.md
に書き込む (ファイルの更新までで、git commit
処理は上の GitHub Actions ワークフローで行う) - ヘルス異常があれば Slack 通知する仕組みも入れた (Slack の Webhook URL は GitHub Secrets として注入)
- 各サイトの
実処理を持つ Node.js スクリプトは、愚直にコーディングした。外部パッケージをインストールしたくなかったので、お手製感が強い。
ドメインの期限切れまで30日を切った時、証明書の期限切れまで10日を切った時は「ヘルス異常」と見なして、Slack 通知するようにした。また、そもそも status.json
がそのサイトから取得できなかった場合はサイトが落ちているものと見なし、通知するようにした。
GitHub リポジトリ直下の README.md
を毎日書き換えるようなスクリプトになったので、
毎日このページさえ開けば、各サイトが落ちていないか、期限切れが迫っていないかを一覧で把握できる。
とりまコレでよきよき。