power
This commit is contained in:
@@ -226,6 +226,89 @@ backup_old_configs() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 清理所有可能冲突的 nginx 配置
|
||||||
|
cleanup_nginx_conflicts() {
|
||||||
|
log_step "清理 nginx 配置冲突..."
|
||||||
|
|
||||||
|
local cleaned=0
|
||||||
|
|
||||||
|
# 1. 清理所有包含此域名的配置文件
|
||||||
|
log_info "搜索包含 ${DOMAIN} 的配置文件..."
|
||||||
|
local conflict_files=$(grep -rl "server_name.*${DOMAIN}" /etc/nginx/ 2>/dev/null | grep -v ".bak-" | grep -v ".bak/")
|
||||||
|
|
||||||
|
if [[ -n "$conflict_files" ]]; then
|
||||||
|
echo "$conflict_files" | while read file; do
|
||||||
|
log_warn "发现冲突配置: $file"
|
||||||
|
|
||||||
|
# 检查是否有多个 server_name 指令
|
||||||
|
local count=$(grep -c "server_name" "$file" 2>/dev/null || echo 0)
|
||||||
|
|
||||||
|
if [[ $count -gt 1 ]]; then
|
||||||
|
# 如果文件中有多个域名,只移除此域名的配置
|
||||||
|
log_warn "文件包含多个域名,仅移除此域名的配置"
|
||||||
|
# 这比较复杂,暂时标记为需要手动处理
|
||||||
|
log_error "需要手动处理: $file"
|
||||||
|
elif [[ $count -eq 1 ]]; then
|
||||||
|
# 如果文件只有此域名,可以安全删除
|
||||||
|
local backup="${file}.bak-conflict-$(date +%s)"
|
||||||
|
mv "$file" "$backup"
|
||||||
|
log_info "已备份并移除冲突配置: $backup"
|
||||||
|
cleaned=$((cleaned + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. 清理 sites-enabled 中的符号链接
|
||||||
|
if [[ -L "${NGINX_ENABLED}/${DOMAIN}.conf" ]]; then
|
||||||
|
rm -f "${NGINX_ENABLED}/${DOMAIN}.conf"
|
||||||
|
log_info "已删除符号链接: ${NGINX_ENABLED}/${DOMAIN}.conf"
|
||||||
|
cleaned=$((cleaned + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. 清理 sites-available 中的配置
|
||||||
|
if [[ -f "${NGINX_AVAILABLE}/${DOMAIN}.conf" ]]; then
|
||||||
|
rm -f "${NGINX_AVAILABLE}/${DOMAIN}.conf"
|
||||||
|
log_info "已删除配置: ${NGINX_AVAILABLE}/${DOMAIN}.conf"
|
||||||
|
cleaned=$((cleaned + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. 清理 conf.d 中所有相关配置
|
||||||
|
local confd_files=$(find /etc/nginx/conf.d/ -name "*${DOMAIN}*.conf" -type f 2>/dev/null)
|
||||||
|
echo "$confd_files" | while read file; do
|
||||||
|
# 排除当前要生成的配置文件
|
||||||
|
if [[ "$file" != "$HTTPS_CONF_FILE" ]] && [[ "$file" != "$HTTP_CONF_FILE" ]]; then
|
||||||
|
local backup="${file}.bak-old-$(date +%s)"
|
||||||
|
mv "$file" "$backup"
|
||||||
|
log_info "已备份旧配置: $backup"
|
||||||
|
cleaned=$((cleaned + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 5. 检查其他可能的配置位置
|
||||||
|
for dir in /etc/nginx/sites-enabled /etc/nginx/sites-available /etc/nginx/conf.d; do
|
||||||
|
if [[ -d "$dir" ]]; then
|
||||||
|
local other_files=$(find "$dir" -name "*.conf" -type f 2>/dev/null)
|
||||||
|
echo "$other_files" | while read file; do
|
||||||
|
if grep -q "server_name.*${DOMAIN}" "$file" 2>/dev/null; then
|
||||||
|
if [[ "$file" != "$HTTPS_CONF_FILE" ]] && [[ "$file" != "$HTTP_CONF_FILE" ]]; then
|
||||||
|
local backup="${file}.bak-extra-$(date +%s)"
|
||||||
|
mv "$file" "$backup"
|
||||||
|
log_warn "发现额外配置并已备份: $backup"
|
||||||
|
cleaned=$((cleaned + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $cleaned -eq 0 ]]; then
|
||||||
|
log_info "未发现配置冲突"
|
||||||
|
else
|
||||||
|
log_success "已清理 $cleaned 个冲突配置"
|
||||||
|
log_warn "建议运行: systemctl restart nginx"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# 检查证书是否已存在且未过期
|
# 检查证书是否已存在且未过期
|
||||||
check_existing_certificate() {
|
check_existing_certificate() {
|
||||||
log_step "检查现有证书..."
|
log_step "检查现有证书..."
|
||||||
@@ -501,6 +584,87 @@ issue_certificate() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 带重试的证书申请函数
|
||||||
|
issue_certificate_with_retry() {
|
||||||
|
local max_retries=3
|
||||||
|
local retry_count=0
|
||||||
|
local wait_seconds=5
|
||||||
|
|
||||||
|
while [[ $retry_count -lt $max_retries ]]; do
|
||||||
|
retry_count=$((retry_count + 1))
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log_step "尝试申请证书 (第 $retry_count/$max_retries 次)..."
|
||||||
|
|
||||||
|
# 调用基本的证书申请函数
|
||||||
|
if issue_certificate; then
|
||||||
|
log_success "✅ 证书申请成功!"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
# 申请失败,分析原因
|
||||||
|
log_warn "⚠️ 第 $retry_count 次申请失败"
|
||||||
|
|
||||||
|
# 检查是否是配置问题导致的失败
|
||||||
|
if grep -q "Invalid response.*404" /var/log/provision-${DOMAIN}.log 2>/dev/null || grep -q "conflicting server name" /var/log/nginx/error.log 2>/dev/null; then
|
||||||
|
log_warn "检测到配置冲突问题,尝试清理并重试..."
|
||||||
|
|
||||||
|
# 再次清理配置
|
||||||
|
cleanup_nginx_conflicts
|
||||||
|
|
||||||
|
# 重新生成 HTTP 配置
|
||||||
|
generate_http_config
|
||||||
|
|
||||||
|
# 完全重启 nginx
|
||||||
|
log_info "重启 nginx 服务..."
|
||||||
|
if systemctl restart nginx >/dev/null 2>&1 || systemctl reload nginx >/dev/null 2>&1 || service nginx restart >/dev/null 2>&1; then
|
||||||
|
log_success "nginx 重启成功"
|
||||||
|
else
|
||||||
|
log_error "nginx 重启失败,请手动检查"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 等待一下让 nginx 完全启动
|
||||||
|
sleep $wait_seconds
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 如果不是最后一次尝试,等待后重试
|
||||||
|
if [[ $retry_count -lt $max_retries ]]; then
|
||||||
|
echo ""
|
||||||
|
log_info "等待 ${wait_seconds} 秒后重试..."
|
||||||
|
sleep $wait_seconds
|
||||||
|
|
||||||
|
# 增加等待时间(指数退避)
|
||||||
|
wait_seconds=$((wait_seconds * 2))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 所有重试都失败
|
||||||
|
log_error "❌ 经过 $max_retries 次尝试,证书申请仍然失败"
|
||||||
|
echo ""
|
||||||
|
log_error "可能的原因:"
|
||||||
|
echo " 1. 域名未正确解析到本服务器"
|
||||||
|
echo " 2. 防火墙阻止了 80 端口"
|
||||||
|
echo " 3. nginx 配置存在冲突"
|
||||||
|
echo " 4. webroot 目录权限不足"
|
||||||
|
echo ""
|
||||||
|
echo "建议的排查步骤:"
|
||||||
|
echo " # 1. 检查域名解析"
|
||||||
|
echo " dig ${DOMAIN}"
|
||||||
|
echo ""
|
||||||
|
echo " # 2. 测试 80 端口"
|
||||||
|
echo " curl -I http://${DOMAIN}/.well-known/acme-challenge/test"
|
||||||
|
echo ""
|
||||||
|
echo " # 3. 检查 nginx 配置"
|
||||||
|
echo " grep -r 'server_name.*${DOMAIN}' /etc/nginx/"
|
||||||
|
echo ""
|
||||||
|
echo " # 4. 检查 webroot 权限"
|
||||||
|
echo " ls -la ${WEBROOT}"
|
||||||
|
echo " sudo chown -R www-data:www-data ${WEBROOT}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# 安装证书到指定位置
|
# 安装证书到指定位置
|
||||||
install_certificate() {
|
install_certificate() {
|
||||||
log_step "安装证书到指定目录..."
|
log_step "安装证书到指定目录..."
|
||||||
@@ -796,6 +960,9 @@ main() {
|
|||||||
install_acme_sh
|
install_acme_sh
|
||||||
setup_webroot
|
setup_webroot
|
||||||
backup_old_configs
|
backup_old_configs
|
||||||
|
|
||||||
|
# 清理可能存在的 nginx 配置冲突
|
||||||
|
cleanup_nginx_conflicts
|
||||||
|
|
||||||
# 检查是否需要申请新证书
|
# 检查是否需要申请新证书
|
||||||
local skip_issue=false
|
local skip_issue=false
|
||||||
@@ -806,12 +973,16 @@ main() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
generate_http_config
|
generate_http_config
|
||||||
|
|
||||||
|
# 在生成配置后再次清理冲突
|
||||||
|
cleanup_nginx_conflicts
|
||||||
|
|
||||||
reload_nginx
|
reload_nginx
|
||||||
|
|
||||||
# 只有在需要申请新证书时才执行验证和申请流程
|
# 只有在需要申请新证书时才执行验证和申请流程
|
||||||
if [[ "$skip_issue" == "false" ]]; then
|
if [[ "$skip_issue" == "false" ]]; then
|
||||||
if check_domain_reachability; then
|
if check_domain_reachability; then
|
||||||
issue_certificate
|
issue_certificate_with_retry
|
||||||
else
|
else
|
||||||
log_error "域名可达性检测失败,无法继续"
|
log_error "域名可达性检测失败,无法继续"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
Reference in New Issue
Block a user