PleskのLet's Encryptの有効期限チェックを作ってみました

エフ
2022-09-20
2022-09-20

Plesk(Linux版)のコントロールパネルから無料のSSL証明書であるLet's Encryptの証明書を設定することができます。


1


3か月ごとに自動的に更新されて、無料ということで便利なのですが、
何かの拍子にこの更新に失敗しているケースがありました。


これではまずいので、更新ができていない場合に拾えるように設定を入れてみました。

Plesk(Linux版)の場合、Let's Encryptを導入すると以下ディレクトリにドメイン名のディレクトリが作られます。

/usr/local/psa/var/modules/letsencrypt/etc/live/ドメイン名/

このディレクトリの中に証明書へのリンクが張られています。

lrwxrwxrwx 1 psaadm root 43 Apr 28 16:21 cert.pem -> ../../archive/ドメイン名/cert**.pem
lrwxrwxrwx 1 psaadm root 44 Apr 28 16:21 chain.pem -> ../../archive/ドメイン名/chain**.pem
lrwxrwxrwx 1 psaadm root 48 Apr 28 16:21 fullchain.pem -> ../../archive/ドメイン名/fullchain**.pem
lrwxrwxrwx 1 psaadm root 46 Apr 28 16:21 privkey.pem -> ../../archive/ドメイン名/privkey**.pem


対象ドメインの証明書を以下で確認できます。
openssl x509 -in /usr/local/psa/var/modules/letsencrypt/etc/live/ドメイン名/cert.pem -text



コマンドをたたいた時の一部を抜粋

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
04:0d:f4:3c:5c:76:d6:e2:96:3c:51:19:14:39:18:d5:2f:72
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=Let's Encrypt, CN=R3
Validity
Not Before: Mar 22 00:27:29 2022 GMT
Not After : Jun 20 00:27:28 2022 GMT
Subject: CN=ドメイン名


「Not Before: Mar 22 00:27:29 2022 GMT」の部分で有効期限を拾い出して更新できているかを管理したい
ということで以下のようなスクリプトで監視することにしました。


***********************************************************************************************
#!/bin/sh

##①アラートファイルのクリア
cat /dev/null > /tmp/alert.file
cat /dev/null > /tmp/check.txt

##②letsencrypt導入有無の判断
if [ ! -d /usr/local/psa/var/modules/letsencrypt/etc/live ]; then
exit 1
fi

##③対象リストの絞り込み ディレクトリのタイムスタンプを直近90日に絞り込み
find /usr/local/psa/var/modules/letsencrypt/etc/live/ -daystart -mtime -90 -type d |cut -d / -f 10 |grep -v '^\s*$' > list.txt



##④各リストに対して証明書期限ファイルの作成
for TGT in `cat list.txt`
do
openssl x509 -in /usr/local/psa/var/modules/letsencrypt/etc/live/$TGT/cert.pem -text |grep "After" | sed s/"Not After : "//g | sed s/" "//g > /tmp/$TGT


##⑤証明書期限20日の絞り込み

ssl=`cat /tmp/$TGT`
limit=`date -d "20 days" +%s`
ssltime=`date -d "$ssl" +%s`

if [ $limit -lt $ssltime ]; then
echo $TGT >> /tmp/check.txt
echo $ssl >> /tmp/check.txt
echo "まだ20日より前" >> /tmp/check.txt
echo -e >> /tmp/check.txt
else
echo $TGT >> /tmp/alert.file
echo $ssl >> /tmp/alert.file
echo -e >> /tmp/alert.file
fi
done
***********************************************************************************************


①期限が迫ったドメイン名をアラートファイルに一時書き出して検知しようと思いますが、
ひとまず繰り返し利用するためにアラートファイルをクリアします。

②そもそもLet's Encryptの導入がなければドメイン名のディレクトリは作られませんので、
こちらを確認し、何もなければスクリプトを終了します。

③Let's Encryptの有効期限が90日であり、すでにLet's Encryptを使用していないドメインのディレクトリを拾っても仕方がないので
ディレクトリを直近90日に絞り込み、ドメイン名だけ抽出します。
「|grep -v '^\s*$'」を入れているのは空白行も拾ってしまうためで、空白行を除外してます。

④有効期限の「Mar 22 00:27:29 2022 GMT」部分だけ拾いたいので、変換したり工夫してます。
もっといい拾い方がある気もします。

⑤Let's Encryptは有効期限が30日を切ると自動更新されますので、
20日を切る証明書だけを拾うようにします。
「Mar 22 00:27:29 2022 GMT」やdateコマンドで出力される「Thu Apr 28 22:44:52 JST 2022」などを
比較しやすいようUNIX時刻に変換します。

$ date
Thu Apr 28 22:44:52 JST 2022

$ date +%s
1651153489

こんな感じ。

これで有効期限が20日を切ったドメインのみalert.fileに吐き出します。


後はこのスクリプトをcronで定期的に実行し、
alert.fileにデータがあれば、メールを流すなどで監視ができました。

あんまりスムーズじゃないかもしれません。