影刀RPA SSL证书监控:到期检测与自动续期提醒
影刀RPA SSL证书监控到期检测与自动续期提醒作者林焱 | 适用人群影刀RPA新手 | 难度★★☆☆☆一、什么情况用这个公司网站突然打不开了排查半天发现是SSL证书过期了——运维忘了续期。用户看到的是「您的连接不是私密连接」的安全警告信任度直接归零。用影刀RPA定时检测所有域名的SSL证书 → 到期前30天/7天/1天分级提醒 → 自动触发续期流程。证书到期前你就知道而不是等用户告诉你。实际场景公司官网证书监控、API网关证书管理、客户网站运维服务、CDN证书到期提醒。这篇文章能解决的问题自动检测SSL证书到期时间多域名批量监控分级告警推送生成证书健康报告二、怎么做店群矩阵自动化突破运营极限2.1 域名配置表在Excel中维护要监控的域名列表域名负责人证书类型CA机构告警方式备注www.company.com张三DVLet’s Encrypt企微主站api.company.com李四OVDigiCert企微邮件API网关admin.company.com王五EVGeoTrust邮件管理后台2.2 影刀主流程┌──────────────────────────────────────────────┐ │ ① 【读取Excel】 │ │ 读取域名配置列表 │ │ ↓ │ │ ② 【遍历列表】 │ │ 对每个域名检查SSL证书 │ │ ↓ │ │ ③ 【执行Python代码】 │ │ 获取SSL证书信息解析到期时间 │  │ ↓ │ │ ④ 【条件判断】 │ │ 分级判断到期天数 │ │ ↓ │ │ ⑤ 【发送通知】 │ │ 推送告警 │ └──────────────────────────────────────────────┘2.3 核心代码importsslimportsocketfromdatetimeimportdatetime,timedeltaimportjsondefcheck_ssl_certificate(domain,port443,timeout10):检查SSL证书信息try:# 创建SSL上下文contextssl.create_default_context()# 建立连接withsocket.create_connection((domain,port),timeouttimeout)assock:withcontext.wrap_socket(sock,server_hostnamedomain)asssock:certssock.getpeercert()# 解析证书信息not_after_strcert.get(notAfter,)subjectcert.get(subject,[])issuercert.get(issuer,[])sancert.get(subjectAltName,[])# 提取通用名称cnforiteminsubject:forkey,valueinitem:ifkeycommonName:cnvalue# 提取颁发者issuer_cnforiteminissuer:forkey,valueinitem:ifkeycommonName:issuer_cnvalue# 解析到期时间# notAfter格式Nov 15 12:00:00 2024 GMTcert_expirydatetime.strptime(not_after_str,%b %d %H:%M:%S %Y %Z)days_left(cert_expiry.date()-datetime.now().date()).daysreturn{domain:domain,cn:cn,issuer:issuer_cn,expiry_date:cert_expiry.strftime(%Y-%m-%d),days_left:days_left,sans:[s[1]forsinsanifs[0]DNS],valid:days_left0,error:None,}exceptssl.SSLErrorase:return{domain:domain,valid:False,error:fSSL错误:{str(e)[:200]},}exceptsocket.timeout:return{domain:domain,valid:False,error:连接超时,}exceptsocket.gaierror:return{domain:domain,valid:False,error:域名解析失败,}exceptExceptionase:return{domain:domain,valid:False,error:f未知错误:{str(e)[:200]},}# 批量检查 domains[row[域名]forrowindomain_config]# 从影刀Excel读取results[]fordomainindomains:print(f检查{domain})resultcheck_ssl_certificate(domain)results.append(result)ifresult[valid]:daysresult[days_left]ifdays30:level紧急ifdays7else警告ifdays14else提醒print(f ⚠️{domain}:{days}天后到期 ({level}))else:print(f ✅{domain}:{days}天后到期)else:print(f ❌{domain}:{result[error]})outputjson.dumps(results,ensure_asciiFalse)2.4 告警分级影刀中对结果进行分级处理【遍历列表】→ results中的每条记录 【条件判断1】 条件valid True 且 days_left 7 → 是【发送企业微信消息】 紧急{domain} SSL证书将在{days_left}天后到期 到期时间{expiry_date} 颁发者{issuer} 请立即续期 【条件判断2】 条件valid True 且 7 days_left 30  → 是【发送邮件】 主题SSL证书到期提醒 - {domain} 正文证书将在{days_left}天后到期请安排续期。 【条件判断3】 条件valid False → 是【发送企业微信消息】 ❌ 错误{domain} 无法获取SSL证书 原因{error}2.5 检查证书链defcheck_certificate_chain(domain,port443):检查完整证书链contextssl.create_default_context()chain_info[]try:withsocket.create_connection((domain,port),timeout10)assock:withcontext.wrap_socket(sock,server_hostnamedomain)asssock:# 获取证书链cert_chainssock.getpeercertchain()ifcert_chain:fori,certinenumerate(cert_chain):subject_cnissuer_cnforitemincert.get(subject,[]):fork,vinitem:ifkcommonName:subject_cnvforitemincert.get(issuer,[]):fork,vinitem:ifkcommonName:issuer_cnv chain_info.append({level:服务器证书ifi0elsef中间证书{i},subject:subject_cn,issuer:issuer_cn,})exceptExceptionase:print(f获取证书链失败{e})returnchain_info2.6 生成监控报告【写入Excel】→ D:\监控\SSL证书监控_{日期}.xlsx Sheet1「概览」 总监控域名 | 正常 | 即将到期 | 已过期 | 检测失败 Sheet2「即将到期」 域名 | 到期日期 | 剩余天数 | 负责人 | 告警方式 Sheet3「证书详情」 域名 | CN | 颁发者 | 到期日期 | SAN列表三、有什么坑坑1CDN/代理后面的证书如果域名前面有CDN如Cloudflare、阿里云CDN你检测到的是CDN的边缘证书不是源站证书。# 如果域名经过了CDN需要绕过CDN直接检测源站# 方法1用源站IP代替域名# 方法2在请求中设置正确的Host头importsslimportsocket[video(video-hne9ueJC-1783724058158)(type-csdn)(url-https://live.csdn.net/v/embed/524992)(image-https://v-blog.csdnimg.cn/asset/b59aed2f01d4fe8583467562aaf4dcfd/cover/Cover0.jpg)(title-temu店群自动化报活动案例)]contextssl.create_default_context()socksocket.create_connection((源站IP,443))ssl_sockcontext.wrap_socket(sock,server_hostnamewww.example.com)坑2多个域名的证书可能是同一张SAN证书Subject Alternative Name一张证书覆盖多个域名。检查主域名就行不要对每个SAN域名重复检查。# 如果检测到SAN列表可以跳过SAN中的域名checked_domainsset()fordomainindomains:ifdomaininchecked_domains:continueresultcheck_ssl_certificate(domain)checked_domains.add(domain)ifresult.get(sans):forsaninresult[sans]:checked_domains.add(san)坑3非标准端口不是所有HTTPS服务都在443端口。台账中应该包含端口号域名端口api.company.com8443admin.company.com443坑4自签名证书和内网证书内网用的自签名证书标准SSL验证会失败。defcheck_self_signed_cert(domain,port443):检查自签名证书不验证证书链contextssl._create_unverified_context()# 不验证# 其余逻辑同上坑5检测频率SSL证书一般一年才到期不必每天检查。每周检查一次足够但到期前30天内建议每天检查。# 根据距离到期天数调整检测频率ifdays_left30:scheduleweekly# 每周检查elifdays_left7:scheduledaily# 每天检查else:schedulehourly# 每小时检查总结用影刀做SSL证书监控核心是用Python的ssl库直接连接443端口获取证书信息。注意CDN后端真实证书的检测、SAN证书的重复检测问题、内网自签名证书的特殊处理。