From cd346ec94be7169ef2dd3e1ff6fb2f471e8fcdb3 Mon Sep 17 00:00:00 2001 From: jingrow Date: Thu, 1 Jan 2026 19:38:34 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E8=AF=81=E4=B9=A6?= =?UTF-8?q?=E7=94=B3=E8=AF=B7=E9=80=BB=E8=BE=91=EF=BC=8C=E5=90=8C=E4=B8=80?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=9A=84=E5=A4=9A=E4=B8=AA=E5=9F=9F=E5=90=8D?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=88=B0=E4=B8=80=E4=B8=AA=E8=AF=81=E4=B9=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 按路由处理域名,而不是按域名处理 - 同一路由中的多个域名合并到一个证书申请(使用 SAN) - 减少证书数量,简化管理 - 符合最佳实践:一个证书包含多个相关域名 优势: - 减少证书数量(从 N 个减少到 1 个) - 减少续期次数 - 降低 Let's Encrypt API 调用频率 - 简化证书管理 示例: - 路由包含 jingrowtools.cn 和 www.jingrowtools.cn - 现在会申请一个包含两个域名的证书(SAN) - 而不是分别申请两个独立证书 --- ssl_manager/route_watcher.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/ssl_manager/route_watcher.py b/ssl_manager/route_watcher.py index 7211a98..ed131c4 100755 --- a/ssl_manager/route_watcher.py +++ b/ssl_manager/route_watcher.py @@ -154,20 +154,28 @@ class RouteWatcher: def process_new_domains(self): """处理新域名""" routes = self.get_all_routes() - new_domains = set() - # 从路由中提取所有域名 + # 按路由处理,同一路由的多个域名合并到一个证书 for route in routes: route_value = route.get('value', {}) # 跳过禁用的路由(status=0 表示禁用) if route_value.get('status') == 0: continue + + # 从路由中提取所有域名 domains = self.extract_domains_from_route(route) - new_domains.update(domains) - - # 处理需要申请证书的域名 - for domain in new_domains: - if self.should_request_cert(domain): + if not domains: + continue + + # 过滤出需要申请证书的域名 + domains_to_request = [d for d in domains if self.should_request_cert(d)] + + if not domains_to_request: + continue + + # 如果只有一个域名,单独申请 + if len(domains_to_request) == 1: + domain = domains_to_request[0] logger.info(f"发现新域名,准备申请证书: {domain}") try: if self.ssl_manager.request_certificate(domain): @@ -176,6 +184,18 @@ class RouteWatcher: logger.error(f"证书申请失败: {domain}") except Exception as e: logger.error(f"处理域名异常 {domain}: {e}") + else: + # 多个域名,合并到一个证书申请(使用 SAN) + primary_domain = domains_to_request[0] + additional_domains = domains_to_request[1:] + logger.info(f"发现同一路由中的多个域名,合并申请证书: {primary_domain} + {additional_domains}") + try: + if self.ssl_manager.request_certificate(primary_domain, additional_domains): + logger.info(f"证书申请成功: {primary_domain} (包含 {len(additional_domains)} + 1} 个域名)") + else: + logger.error(f"证书申请失败: {primary_domain} + {additional_domains}") + except Exception as e: + logger.error(f"处理域名异常 {primary_domain} + {additional_domains}: {e}") def run(self, interval: int = 60): """运行监听服务"""