ssl证书到期提醒
第一步:在青龙面板中添加脚本
- 登录青龙面板。
- 点击左侧菜单的 “脚本管理”。
- 点击右上角的 “+”号(新建)。
- 类型选择:
Python。 - 文件名填写:
check_ssl.py。 - 父目录留空即可。
- 把下面的代码完整复制粘贴进去,只需要修改代码里
domains列表中的网址即可:
import ssl
import socket
import datetime
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.utils import formataddr
# ================= ⚙️ 配置区域 =================
# 1. 邮件发送设置
# 【登录和发送都用这个邮箱】
sender_mail = '发件邮箱@qq.com'
sender_name = 'SSL监控小助手'
# 【⚠️重要】这里填授权码 (主账号的)
sender_pass = ''
# 2. 接收邮箱
receiver_list = ['收件邮箱@qq.com']
# 3. 监控列表 (新增 renew_url 字段)
# 您可以在 renew_url 里填入阿里云/腾讯云/宝塔的后台地址
domain_config = [
{
'url': 'www.lsky.pro',
'name': '兰空图床',
'renew_url': 'https://console.cloud.tencent.com/ssl' # 示例:腾讯云控制台
},
{
'url': 'qinglong.online',
'name': '青龙面板',
'renew_url': 'http://192.168.1.5:5700' # 示例:内网IP
},
{
'url': 'openwrt.org',
'name': 'N1盒子',
'renew_url': 'https://yoursite.com/renew' # 示例
},
{
'url': 'www.ip38.com',
'name': 'IP检测服务',
'renew_url': 'https://yoursite.com/renew'
},
{
'url': 'www.fnnas.com',
'name': '飞牛服务',
'renew_url': 'https://yoursite.com/renew'
}
]
# 4. 报警阈值 (剩下多少天开始报警)
ALERT_DAYS = 15
# ===============================================
def check_ssl(domain):
"""检查单个域名的证书"""
try:
ctx = ssl.create_default_context()
conn = ctx.wrap_socket(socket.socket(socket.AF_INET), server_hostname=domain)
conn.settimeout(5.0)
conn.connect((domain, 443))
cert = conn.getpeercert()
conn.close()
expire_date_str = cert['notAfter']
expire_date = datetime.datetime.strptime(expire_date_str, "%b %d %H:%M:%S %Y %Z")
remaining_days = (expire_date - datetime.datetime.utcnow()).days
return True, remaining_days, expire_date.strftime("%Y-%m-%d")
except Exception as e:
return False, str(e), "未知"
def send_alert_email(alert_data_list):
"""发送 HTML 报警邮件"""
if not sender_pass:
print("❌ 未配置授权码,无法发送报警邮件")
return
# 1. 构建 HTML 表格内容
rows_html = ""
for item in alert_data_list:
name = item['name']
domain = item['domain']
days = item['days']
info = item['info']
link = item['renew_url']
is_error = item['is_error']
# 样式处理:错误用红色背景,过期警告用黄色背景
if is_error:
status_html = f'<span style="color: white; background-color: #d9534f; padding: 2px 6px; border-radius: 4px;">检测失败</span>'
desc_html = f'<span style="color: #d9534f;">{info}</span>'
else:
status_html = f'<span style="color: white; background-color: #f0ad4e; padding: 2px 6px; border-radius: 4px;">仅剩 {days} 天</span>'
desc_html = f'<span style="color: #666;">过期时间: {info}</span>'
rows_html += f'''
<div style="padding: 10px; border-bottom: 1px solid #eee;">
<div style="font-size: 16px; font-weight: bold; color: #333;">
{name} <span style="font-size: 14px; font-weight: normal; color: #888;">({domain})</span>
</div>
<div style="margin-top: 5px;">
{status_html} {desc_html}
</div>
<div style="margin-top: 8px;">
👉 <a href="{link}" target="_blank" style="color: #007bff; text-decoration: none; font-weight: bold;">立即续签 ></a>
</div>
</div>
'''
# 2. 完整的 HTML 结构
html_content = f'''
<div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #ddd; border-radius: 8px; overflow: hidden;">
<div style="background-color: #d9534f; color: white; padding: 15px; text-align: center;">
<h2 style="margin: 0; font-size: 20px;">⚠️ SSL 证书过期预警</h2>
</div>
<div style="padding: 15px;">
<p style="color: #555;">监控小助手发现以下服务证书异常,请及时处理:</p>
{rows_html}
</div>
<div style="background-color: #f8f9fa; padding: 10px; text-align: center; color: #999; font-size: 12px;">
此邮件由青龙面板自动发送,正常状态下不会打扰。
</div>
</div>
'''
msg = MIMEText(html_content, 'html', 'utf-8')
msg['From'] = formataddr((Header(sender_name, 'utf-8').encode(), sender_mail))
msg['To'] = ",".join(receiver_list)
msg['Subject'] = Header(f'⚠️ 证书报警: 有 {len(alert_data_list)} 个服务需要续期', 'utf-8')
try:
s = smtplib.SMTP_SSL('smtp.qq.com', 465)
s.login(sender_mail, sender_pass)
s.sendmail(sender_mail, receiver_list, msg.as_string())
s.quit()
print(f"✅ 报警邮件已发送给: {receiver_list[0]}")
except Exception as e:
print(f"❌ 邮件发送失败: {e}")
def main():
print(f"⏰ 开始检查 SSL 证书 (阈值: {ALERT_DAYS}天)...")
print("-" * 40)
alert_data_list = []
for item in domain_config:
domain = item['url']
name = item['name']
renew_url = item.get('renew_url', '#') # 获取续签链接,没有则为空
status, days, exp_date = check_ssl(domain)
if status:
if days < ALERT_DAYS:
print(f"⚠️ {name} 证书告急!(剩 {days} 天)")
alert_data_list.append({
'name': name,
'domain': domain,
'days': days,
'info': exp_date,
'renew_url': renew_url,
'is_error': False
})
else:
print(f"✅ [{name}] 剩余 {days} 天")
else:
print(f"❌ {name} 检测失败")
alert_data_list.append({
'name': name,
'domain': domain,
'days': 0,
'info': days, # 这里存报错信息
'renew_url': renew_url,
'is_error': True
})
print("-" * 40)
if alert_data_list:
print(f"😱 发现 {len(alert_data_list)} 个异常,正在发送通知...")
send_alert_email(alert_data_list)
else:
print("🎉 所有服务证书正常,无需打扰。")
if __name__ == "__main__":
main()
- 点击右下角的 “保存”。
第二步:添加定时任务
- 点击左侧菜单的 “定时任务”。
- 点击右上角的 “新建任务”。
- 名称:
SSL证书检查。 - 命令/脚本:
task check_ssl.py。 - 定时规则:
0 9 1 * * - 这个规则的意思是:每月 1 号的上午 9 点 0 分 执行一次。
- 点击 “确定”。
第三步:配置通知(最关键的一步)
第一步:开启 QQ 邮箱的“发信服务”
这是唯一稍微麻烦的一步,但只需要做一次,以后永久稳定。
- 电脑登录网页版 QQ 邮箱。
- 点击左上角的 “设置” -> “账号”。
- 向下滑动,找到 “POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务”。
- 找到 “POP3/SMTP服务”,如果没开启,点击“开启”。
- 系统会让你发个短信验证,验证后它会给你一串 英文授权码(不是你的 QQ 密码!)。
- 请把这串授权码复制下来,一定要保存好。
第二步:修改完记得点“保存”并测试
- 修改代码顶部的
sender_mail和sender_pass。 - 保存后,点击 “运行”。
- 如果你的ssl证书小于15天,您的手机应该会收到一封来自“青龙面板 SSL监控”的邮件。
评论 (0)