一 背景
今天,打开我自己搭建的一些网站,发现无法访问了,原因是SSL证书已经过期。觉得很奇怪,acme.sh是有自动续期的,以前也是一直好好的,不知为何居然没有自动续期,然后自己也不知道,导致接近一个上午我的博客都是无法访问的。原因可能是自动续期的时候,受网络波动,导致没续期成功,而可能没有后续的重试续期机制,导致了这次的问题。
基于这次的教训,于是花了中午的时间写了一下定时监控脚本,避免下次再出现类似的事情。
二 脚本
脚本的大致逻辑是,先获取证书剩余的时间(秒),判断剩余时间是否已经达到了强制更新的时间阈值,如有达到则强制更新并钉钉发送结果;如果时间没达到强制更新的时间阈值但是已经达到了告警的阈值,则发送钉钉告警消息。
具体脚本如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 自己的域名
domain=example.com
# 钉钉token
dingding_token=替换成自己的钉钉群机器人TOKEN
# 提前5天开始提醒
alam_before_day=$((5*24*60*60))
# 到最后1天还未更新证书则强制更
force_update_before_day=$((1*24*60*60))
function getremaintime()
{
expire_date_utc=`/root/.acme.sh/acme.sh --list | grep ${domain} | awk '{print $11" "$12" "$13" "$14" "$15" "$16}' `
expire_time=`date -d "${expire_date_utc}" +"%s"`
now_time=`date +"%s"`
remain_time=`expr $expire_time - $now_time`
}
getremaintime
if [ $remain_time -lt $force_update_before_day ]; then
# 强制更新证书
/root/.acme.sh/acme.sh --renew -f -d ${domain}
# 判断强制更新是否成功
getremaintime
if [ $remain_time -lt $force_update_before_day ]; then
curl "https://oapi.dingtalk.com/robot/send?access_token=${dingding_token}" -H 'Content-Type: application/json' -d "{\"msgtype\": \"text\",\"text\": {\"content\": \"通知告警:${domain}域名ssl证书即将过期,强制刷新失败,请尽快人工干预.\"}}"
else
curl "https://oapi.dingtalk.com/robot/send?access_token=${dingding_token}" -H 'Content-Type: application/json' -d "{\"msgtype\": \"text\",\"text\": {\"content\": \"通知:${domain}域名ssl证书强制刷新成功\"}}"
fi
exit 0
fi
if [ $remain_time -lt $alam_before_day ]; then
remain_day=`expr $remain_time / 24 / 60 / 60`
curl "https://oapi.dingtalk.com/robot/send?access_token=${dingding_token}" -H 'Content-Type: application/json' -d "{\"msgtype\": \"text\",\"text\": {\"content\": \"通知告警:${domain}域名ssl证书即将过期,剩余时间:${remain_day}天\"}}"
exit 0
fi
然后可能通过crontab定时每天某个时刻执行检查一下
增加以上脚本定时检查,等于是自动续期有了双重保障,尽可能的避免了证书失效而不能及时发现的尴尬局面。