diff --git a/create_new_domain_cert.sh b/create_new_domain_cert.sh index 3cfa1bb..c7c974b 100755 --- a/create_new_domain_cert.sh +++ b/create_new_domain_cert.sh @@ -421,34 +421,83 @@ issue_certificate() { local tmp_out=$(mktemp) local tmp_err=$(mktemp) - "$ACME_SH" --issue -d "$DOMAIN" --webroot "$WEBROOT" > >(tee "$tmp_out") 2> >(tee "$tmp_err" >&2) + # 执行证书申请 + "$ACME_SH" --issue -d "$DOMAIN" --webroot "$WEBROOT" > >(tee -a "$tmp_out") 2> >(tee -a "$tmp_err" >&2) local ret=$? - # 分析结果 - if [[ $ret -eq 0 ]]; then - # 检查输出是否包含证书内容 - if grep -q "-----END CERTIFICATE-----" "$tmp_out" || grep -q "-----END CERTIFICATE-----" "$tmp_err"; then - log_success "✅ 证书申请成功!" - rm -f "$tmp_out" "$tmp_err" - return 0 - else - log_warn "证书申请命令返回成功,但未检测到证书内容" - log_info "输出内容:" - cat "$tmp_out" - cat "$tmp_err" - rm -f "$tmp_out" "$tmp_err" - return 0 + # 合并所有输出 + local all_output=$(cat "$tmp_out" "$tmp_err" 2>/dev/null) + + # 智能识别各种成功/跳过情况 + local success=false + local skip_reason="" + + # 情况1: 返回码为0且包含证书 + if [[ $ret -eq 0 ]] && echo "$all_output" | grep -q "-----END CERTIFICATE-----"; then + success=true + log_success "✅ 证书申请成功!(新证书)" + fi + + # 情况2: 域名无变化,跳过申请(acme.sh认为不需要重复申请) + if echo "$all_output" | grep -qE "Domains not changed|Skipping|already issued|Your cert is in"; then + success=true + skip_reason=$(echo "$all_output" | grep -E "Domains not changed|Skipping|already issued|Your cert is in" | head -n1) + + # 提取证书路径 + local cert_path=$(echo "$all_output" | grep "Your cert is in:" | head -n1 | sed 's/.*Your cert is in: //') + if [[ -n "$cert_path" ]]; then + log_success "✅ 证书已存在且有效" + log_info "证书位置: $cert_path" + + # 验证证书文件是否存在 + if [[ -f "$cert_path" ]] || [[ -f "${cert_path%.cer}.pem" ]] || [[ -f "${cert_path%.cer}.key" ]]; then + log_info "✅ 证书文件验证通过" + fi fi + + if echo "$all_output" | grep -q "Domains not changed"; then + log_info "证书信息未变化,跳过重复申请" + fi + if echo "$all_output" | grep -q "Skipping"; then + local next_renewal=$(echo "$all_output" | grep "Next renewal time" | head -n1) + log_info "$next_renewal" + fi + fi + + # 情况3: 返回码非0,但证书已存在(某些版本的acme.sh会这样) + if [[ $ret -ne 0 ]] && [[ -f "/root/.acme.sh/${DOMAIN}_ecc/${DOMAIN}.cer" ]] || [[ -f "/root/.acme.sh/${DOMAIN}/${DOMAIN}.cer" ]]; then + success=true + log_warn "⚠️ acme.sh 返回非零 ($ret),但证书已存在" + log_info "继续使用现有证书" + + # 显示错误信息(但不退出) + echo "" + log_warn "警告信息:" + echo "$all_output" | tail -n 5 + fi + + # 清理临时文件 + rm -f "$tmp_out" "$tmp_err" + + # 最终判断 + if [[ "$success" == "true" ]]; then + return 0 else + # 真正的错误情况 log_error "❌ 证书申请失败 (返回码: $ret)" echo "" - echo "========== 错误输出 ==========" - cat "$tmp_err" - echo "==============================" + echo "========== 完整输出 ==========" + echo "$all_output" + echo "===============================" echo "" - log_error "请检查日志: $LOG_FILE" - rm -f "$tmp_out" "$tmp_err" - exit 1 + log_error "请检查以上输出并确认:" + echo " 1. 域名是否正确解析到此服务器" + echo " 2. 防火墙是否开放 80 和 443 端口" + echo " 3. nginx 是否正常运行" + echo " 4. webroot 目录是否可写" + echo "" + log_error "详细日志: $LOG_FILE" + return 1 fi }