fix: 添加自动创建/更新 webroot 路由功能,修复证书申请时的路由匹配问题
- 新增 ensure_webroot_route 方法,自动创建或更新 APISIX webroot 路由 - 支持为指定域名创建带 host 字段的路由,确保正确匹配 - 在申请证书前自动确保 webroot 路由存在并配置正确 - 设置路由优先级为 99999,确保优先匹配 /.well-known/acme-challenge/* 路径 - 使用 serverless-pre-function 插件从 /var/www/certbot 目录读取验证文件 - 修复了证书申请时因路由匹配问题导致的 404 错误
This commit is contained in:
parent
3478db383e
commit
db30f3d7f1
@ -295,6 +295,78 @@ class APISIXSSLManager:
|
|||||||
logger.error(f"上传证书到 APISIX 失败: {e}")
|
logger.error(f"上传证书到 APISIX 失败: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def ensure_webroot_route(self, domain: str = None) -> bool:
|
||||||
|
"""确保 webroot 路由存在并正确配置
|
||||||
|
|
||||||
|
Args:
|
||||||
|
domain: 域名,如果提供则创建针对该域名的路由,否则创建通用路由
|
||||||
|
"""
|
||||||
|
if domain:
|
||||||
|
route_id = f"certbot-webroot-{domain.replace('.', '-')}"
|
||||||
|
else:
|
||||||
|
route_id = "certbot-webroot"
|
||||||
|
|
||||||
|
route_url = f"{self.apisix_admin_url}/apisix/admin/routes/{route_id}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 检查路由是否存在
|
||||||
|
response = self.session.get(route_url, timeout=10)
|
||||||
|
|
||||||
|
route_config = {
|
||||||
|
"uri": "/.well-known/acme-challenge/*",
|
||||||
|
"name": route_id,
|
||||||
|
"priority": 99999,
|
||||||
|
"plugins": {
|
||||||
|
"serverless-pre-function": {
|
||||||
|
"phase": "rewrite",
|
||||||
|
"functions": [
|
||||||
|
"return function(conf, ctx) local uri = ngx.var.uri; if not uri then uri = ctx.var.uri; end local token = string.match(uri, \"^/%.well%-known/acme%-challenge/(.+)$\"); if not token then ngx.status = 404; ngx.say(\"Token not found. URI: \" .. (uri or \"nil\")); return; end; local path = \"/var/www/certbot/.well-known/acme-challenge/\" .. token; local file = io.open(path, \"r\"); if file then local content = file:read(\"*all\"); file:close(); ngx.header.content_type = \"text/plain\"; ngx.say(content); else ngx.status = 404; ngx.say(\"File not found: \" .. path); end end"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"status": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 如果指定了域名,设置 host 字段以确保正确匹配
|
||||||
|
if domain:
|
||||||
|
route_config["host"] = domain
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
# 路由存在,检查是否需要更新
|
||||||
|
existing_route = response.json().get('value', {})
|
||||||
|
existing_priority = existing_route.get('priority', 0)
|
||||||
|
existing_host = existing_route.get('host')
|
||||||
|
|
||||||
|
# 检查是否需要更新(优先级或 host 不匹配)
|
||||||
|
needs_update = (existing_priority < 99999) or (domain and existing_host != domain)
|
||||||
|
|
||||||
|
if needs_update:
|
||||||
|
logger.info(f"更新 webroot 路由: {route_id}")
|
||||||
|
response = self.session.put(route_url, json=route_config, timeout=10)
|
||||||
|
if response.status_code in [200, 201]:
|
||||||
|
logger.info("Webroot 路由更新成功")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.warning(f"Webroot 路由更新失败: {response.status_code} - {response.text}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
logger.debug(f"Webroot 路由已存在且配置正确: {route_id}")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
# 路由不存在,创建它
|
||||||
|
logger.info(f"创建 webroot 路由: {route_id}")
|
||||||
|
response = self.session.put(route_url, json=route_config, timeout=10)
|
||||||
|
if response.status_code in [200, 201]:
|
||||||
|
logger.info("Webroot 路由创建成功")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logger.error(f"Webroot 路由创建失败: {response.status_code} - {response.text}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"确保 webroot 路由时出错: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def request_certificate(self, domain: str, additional_domains: List[str] = None, max_retries: int = 3) -> bool:
|
def request_certificate(self, domain: str, additional_domains: List[str] = None, max_retries: int = 3) -> bool:
|
||||||
"""申请 Let's Encrypt 证书
|
"""申请 Let's Encrypt 证书
|
||||||
|
|
||||||
@ -303,6 +375,9 @@ class APISIXSSLManager:
|
|||||||
additional_domains: 额外域名列表
|
additional_domains: 额外域名列表
|
||||||
max_retries: 最大重试次数(默认3次)
|
max_retries: 最大重试次数(默认3次)
|
||||||
"""
|
"""
|
||||||
|
# 确保 webroot 路由存在(为当前域名创建)
|
||||||
|
self.ensure_webroot_route(domain)
|
||||||
|
|
||||||
domains = [domain]
|
domains = [domain]
|
||||||
if additional_domains:
|
if additional_domains:
|
||||||
domains.extend(additional_domains)
|
domains.extend(additional_domains)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user