**注意: ** acme.sh默认自带续期功能,前提是不要自己调整证书路径!
免费证书都是3个月到期,需要手动续期,所以写了一个监控加自动续期的服务,有兴趣的可以试一试
import ssl import socket import requests import schedule import time from datetime import datetime import subprocess
# Telegram Bot设置 TELEGRAM_TOKEN = '' TELEGRAM_CHAT_ID = ''
# 储存域名列表 domains = [ 'tool.wangwangit.com' ]
def send_telegram_message(message): url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage" data = { "chat_id": TELEGRAM_CHAT_ID, "text": message } requests.post(url, data=data)
def get_ssl_expiry_date_from_shell(hostname, port=443): cmd = f"echo | openssl s_client -servername {hostname} -connect \"{hostname}:{port}\" 2>/dev/null | openssl x509 -noout -dates" process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = process.communicate() if process.returncode != 0: return f"Error executing command: {err.decode().strip()}" return out.decode().strip()
def renew_ssl(domain): subprocess.run(['nginx', '-s', 'stop']) time.sleep(10) # 等待nginx停止 subprocess.run(['acme.sh', '--issue', '-d', domain, '--standalone', '--force']) time.sleep(30) # 等待证书申请 subprocess.run(['nginx']) subprocess.run(['nginx', '-s', 'reload']) time.sleep(10) # 等待nginx重启
def format_expiry_date(date_str): try: # 提取日期字符串并转换为datetime对象 expiry_date = datetime.strptime(date_str, '%b %d %H:%M:%S %Y %Z') # 返回格式化的日期字符串 return expiry_date.strftime('%Y-%m-%d %H:%M:%S') except ValueError: return date_str # 返回原始字符串,如果格式不匹配
def check_all_domains(): messages = [] for domain in domains: ssl_dates = get_ssl_expiry_date_from_shell(domain) expiry_date_line = ssl_dates.split('\n')[1] if 'notAfter' in ssl_dates else ssl_dates expiry_date = expiry_date_line.split('=')[1] if 'notAfter' in expiry_date_line else "Unknown" formatted_date = format_expiry_date(expiry_date) if "Error" in ssl_dates or "Unknown" in expiry_date: message = f"{domain} SSL证书检查失败:{formatted_date},请手动检查。" messages.append(message) else: message = f"{domain} SSL证书状态正常,有效期至 {formatted_date}。" messages.append(message)
# 将所有消息发送到Telegram send_telegram_message("\n".join(messages))
# 设置定时任务 schedule.every().day.at("10:00").do(check_all_domains)
# 运行定时任务 while True: schedule.run_pending() time.sleep(1)
|
运行情况如下: