如何让certbot在letsencrypt证书成功续期时发送邮件通知?
实现certbot成功续期邮件通知的配置方法
核心触发逻辑梳理
certbot本身自带分层触发的hook机制,完全可以匹配你现有配置的运行场景,不需要改动已经正常工作的Nginx重载post-hook逻辑:
- 你目前在用的
post-hook:只要certbot启动了续期任务(无论最终成功或失败),任务收尾时就会触发,适合放置无状态的服务重载命令 - 专门对应成功场景的
renew-hook:仅当证书实际完成续期、生成了新的证书文件时才会触发,如果续期失败、或者证书没到续期阈值根本未执行续期操作,这个hook完全不会触发——刚好就是加成功续期通知需要的挂载点。
具体配置步骤
1. 准备系统邮件发送能力
Ubuntu环境下不需要额外搭建独立邮件服务,用系统自带的mail命令即可完成发送,先安装基础工具:
apt install mailutils
安装过程中按照向导配置好发件SMTP信息,确保手动从命令行发测试邮件能正常收到即可。
2. 配置成功续期通知逻辑
两种实现方式可以任选,和你现有的post-hook配置习惯完全兼容:
方式A:直接在现有certbot配置中追加规则,适合简单场景
找到你现在写post-hook = systemctl reload nginx的配置位置(全局配置在/etc/letsencrypt/cli.ini,单证书配置在/etc/letsencrypt/renewal/对应域名.conf),在同一段配置下追加renew-hook规则,利用certbot内置自动注入的环境变量,把续期关键信息放到邮件内容里:
# 原有配置保留不动 post-hook = systemctl reload nginx # 新增的成功续期通知规则 renew-hook = echo "续期完成时间:$(date '+%Y-%m-%d %H:%M:%S')|续期域名:$RENEWED_DOMAINS|证书路径:$RENEWED_LINEAGE" | mail -s "Let's Encrypt 证书续期成功通知" 你的运维邮箱@example.com
这里用到的两个环境变量是certbot触发hook时自动传入的,不需要额外写脚本捕获:
$RENEWED_DOMAINS:本次成功续期的所有域名列表$RENEWED_LINEAGE:本次续期的证书文件存储路径
方式B:用certbot自动扫描的hook目录存放独立脚本,适合自定义需求
certbot会自动扫描/etc/letsencrypt/renewal-hooks/下三个分类目录的可执行脚本,不需要手动在配置文件里声明路径,长期管理更清晰:
- 新建续期成功专属的通知脚本:
脚本内容可根据通知需求自定义,比如加上Nginx重载状态、服务器剩余磁盘空间等信息:nano /etc/letsencrypt/renewal-hooks/renew/send_success_mail.sh#!/bin/bash SUBJECT="证书续期成功:$RENEWED_DOMAINS" CONTENT=" 续期完成时间:$(date '+%Y-%m-%d %H:%M:%S') 续期覆盖域名:$RENEWED_DOMAINS 证书存储路径:$RENEWED_LINEAGE 已自动完成Nginx服务重载,服务状态正常。 " echo "$CONTENT" | mail -s "$SUBJECT" 你的运维邮箱@example.com - 给脚本加可执行权限,否则certbot会静默跳过不执行:
chmod +x /etc/letsencrypt/renewal-hooks/renew/send_success_mail.sh
3. 本地验证配置有效性
不需要等3个月后的真实续期周期再测试,直接用certbot的干跑命令模拟全流程即可:
certbot renew --dry-run
跑完检查两点就算配置生效:
- 原有post-hook的Nginx重载逻辑正常执行
- 运维邮箱收到了对应成功续期的通知邮件
实际运维中容易踩的坑
- 别把成功通知逻辑塞到post-hook里:post-hook不管续期成没成都触发,最后会变成失败也发成功邮件,完全搞混告警逻辑
- 放在hook自动扫描目录下的脚本一定要加可执行权限,不然certbot根本不会运行,还不会在显眼位置报错,只会在debug日志里提一句权限不够,排查成本很高
- 没必要在renew-hook里重复写Nginx重载命令,你现有的post-hook本来就会在续期流程收尾时执行,写多了反而可能重复触发服务重载
内容的提问来源于stack exchange,提问作者bernhard_kfu
相关产品推荐
相关产品推荐

