fix: 全面改进SSL证书部署逻辑

**Certbot改进(方案1)**:
- Ubuntu/Debian优先使用snap安装(官方推荐)
- 避免Python依赖冲突(urllib3.contrib.appengine问题)
- snap失败自动降级到apt安装
- 添加安装验证逻辑

**acme.sh改进(方案2-4)**:
- 改用两步安装:先下载到临时文件,验证后执行
- 检查下载文件大小和内容完整性
- 验证脚本内容(检测acme.sh关键词)
- 增加等待时间:2秒→5秒
- 统一三个方案(Let's Encrypt/ZeroSSL/Buypass)

**诊断增强**:
- 添加安装位置查找功能
- 改进错误提示信息
- 提供更详细的排查步骤

**兼容性**:
- 支持Ubuntu/Debian (apt)
- 支持CentOS/RHEL (yum/dnf)
- 支持openSUSE (zypper)
- 兼容宝塔面板环境
This commit is contained in:
WanWanYun
2025-11-13 09:57:28 +08:00
parent 72ec10ef4e
commit 58d2038ed3

View File

@@ -1260,21 +1260,50 @@ ssl_fallback() {
deploy_certbot() {
print_step "使用 Certbot 部署SSL证书..."
# 安装certbot
case $PKG_MANAGER in
apt)
apt-get install -y certbot python3-certbot-nginx
;;
yum)
yum install -y certbot python3-certbot-nginx
;;
dnf)
dnf install -y certbot python3-certbot-nginx
;;
zypper)
zypper install -y certbot python3-certbot-nginx
;;
esac
# 检查certbot是否已安装
if ! command -v certbot &> /dev/null; then
print_info "正在安装 Certbot..."
# 安装certbot
case $PKG_MANAGER in
apt)
# Ubuntu/Debian: 优先使用snap官方推荐避免Python依赖冲突
if command -v snap &> /dev/null; then
print_info "使用snap安装Certbot官方推荐方式..."
snap install --classic certbot 2>/dev/null || true
ln -sf /snap/bin/certbot /usr/bin/certbot 2>/dev/null || true
# 验证snap安装是否成功
if /snap/bin/certbot --version &> /dev/null; then
print_success "Certbot (snap版) 安装成功"
else
print_warning "snap安装失败尝试apt安装..."
apt-get install -y certbot python3-certbot-nginx
fi
else
print_info "snap不可用使用apt安装..."
apt-get install -y certbot python3-certbot-nginx
fi
;;
yum)
yum install -y certbot python3-certbot-nginx
;;
dnf)
dnf install -y certbot python3-certbot-nginx
;;
zypper)
zypper install -y certbot python3-certbot-nginx
;;
esac
# 最终验证certbot是否可用
if ! command -v certbot &> /dev/null; then
print_error "Certbot安装失败"
return 1
fi
else
print_success "Certbot 已安装: $(certbot --version 2>&1 | head -1)"
fi
# 申请证书使用webroot模式不自动修改Nginx配置
echo ""
@@ -1312,28 +1341,65 @@ deploy_acme_letsencrypt() {
echo ""
print_info "正在安装 acme.sh..."
# 检测是否在中国大陆,使用镜像加速
# 检测网络环境,选择下载源
if curl -s --connect-timeout 3 https://www.google.com > /dev/null 2>&1; then
# 海外网络 - 使用官方源
print_info "使用官方源安装..."
curl -fsSL https://get.acme.sh | sh
install_result=$?
INSTALL_URL="https://get.acme.sh"
else
# 中国大陆 - 使用Gitee镜像(官方方法)
# 中国大陆 - 使用Gitee镜像
print_info "检测到国内网络使用Gitee镜像加速..."
# 设置环境变量让acme.sh使用Gitee源
INSTALL_URL="https://gitee.com/neilpang/acme.sh/raw/master/acme.sh"
export ACME_USE_GITEE=1
curl -fsSL https://gitee.com/neilpang/acme.sh/raw/master/acme.sh | sh
install_result=$?
fi
# 重新加载环境变量
source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true
# 改进的安装流程:先下载到临时文件,验证后再执行
TEMP_INSTALL_SCRIPT="/tmp/acme-install-$$.sh"
print_info "正在下载安装脚本..."
# 等待文件系统同步
sleep 2
if curl -fsSL "$INSTALL_URL" -o "$TEMP_INSTALL_SCRIPT"; then
# 检查下载的文件
if [[ -f "$TEMP_INSTALL_SCRIPT" ]]; then
FILE_SIZE=$(stat -c%s "$TEMP_INSTALL_SCRIPT" 2>/dev/null || stat -f%z "$TEMP_INSTALL_SCRIPT" 2>/dev/null || echo "0")
if [[ $FILE_SIZE -gt 1000 ]]; then
print_success "安装脚本下载成功 (${FILE_SIZE} bytes)"
# 显示脚本前几行以确认内容
print_info "验证脚本内容..."
if head -3 "$TEMP_INSTALL_SCRIPT" | grep -q "acme.sh"; then
print_success "脚本内容验证通过"
else
print_warning "脚本内容可能异常,但继续尝试..."
fi
# 执行安装
print_info "正在执行安装..."
bash "$TEMP_INSTALL_SCRIPT" --install
install_result=$?
# 清理临时文件
rm -f "$TEMP_INSTALL_SCRIPT"
# 重新加载环境变量
source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true
# 等待文件系统同步 - 增加等待时间
print_info "等待安装完成..."
sleep 5
else
print_error "下载的文件太小 (${FILE_SIZE} bytes),可能下载不完整"
rm -f "$TEMP_INSTALL_SCRIPT"
return 1
fi
else
print_error "安装脚本下载失败"
return 1
fi
else
print_error "无法下载安装脚本"
return 1
fi
# 验证安装是否真正成功(检查目录是否创建)
if [[ $install_result -eq 0 ]] && [[ -d ~/.acme.sh ]] && [[ -f ~/.acme.sh/acme.sh ]]; then
@@ -1348,6 +1414,9 @@ deploy_acme_letsencrypt() {
echo " - HOME变量: $HOME"
echo " - 当前用户: $(whoami)"
echo ""
print_info "尝试查找acme.sh安装位置..."
find /root -name "acme.sh" -type f 2>/dev/null | head -5 || echo " 未找到"
echo ""
print_warning "解决方案:"
echo " 1. 检查网络连接"
echo " 2. 查看安装日志: ls -la ~ | grep acme"
@@ -1428,32 +1497,65 @@ deploy_acme_letsencrypt() {
deploy_acme_zerossl() {
print_step "使用 acme.sh + ZeroSSL 部署SSL证书..."
# 安装acme.sh使用与Let's Encrypt相同的逻辑)
# 安装acme.sh使用改进的安装逻辑)
if [[ ! -d ~/.acme.sh ]]; then
echo ""
print_info "正在安装 acme.sh..."
# 检测网络环境
# 检测网络环境,选择下载源
if curl -s --connect-timeout 3 https://www.google.com > /dev/null 2>&1; then
# 海外网络
print_info "使用官方源安装..."
curl -fsSL https://get.acme.sh | sh
install_result=$?
INSTALL_URL="https://get.acme.sh"
else
# 中国大陆 - 使用Gitee镜像
print_info "检测到国内网络使用Gitee镜像加速..."
INSTALL_URL="https://gitee.com/neilpang/acme.sh/raw/master/acme.sh"
export ACME_USE_GITEE=1
curl -fsSL https://gitee.com/neilpang/acme.sh/raw/master/acme.sh | sh
install_result=$?
fi
# 重新加载环境变量
source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true
# 改进的安装流程:先下载到临时文件,验证后再执行
TEMP_INSTALL_SCRIPT="/tmp/acme-install-$$.sh"
print_info "正在下载安装脚本..."
# 等待文件系统同步
sleep 2
if curl -fsSL "$INSTALL_URL" -o "$TEMP_INSTALL_SCRIPT"; then
if [[ -f "$TEMP_INSTALL_SCRIPT" ]]; then
FILE_SIZE=$(stat -c%s "$TEMP_INSTALL_SCRIPT" 2>/dev/null || stat -f%z "$TEMP_INSTALL_SCRIPT" 2>/dev/null || echo "0")
# 验证安装是否真正成功(检查目录是否创建)
if [[ $FILE_SIZE -gt 1000 ]]; then
print_success "安装脚本下载成功 (${FILE_SIZE} bytes)"
print_info "验证脚本内容..."
if head -3 "$TEMP_INSTALL_SCRIPT" | grep -q "acme.sh"; then
print_success "脚本内容验证通过"
else
print_warning "脚本内容可能异常,但继续尝试..."
fi
print_info "正在执行安装..."
bash "$TEMP_INSTALL_SCRIPT" --install
install_result=$?
rm -f "$TEMP_INSTALL_SCRIPT"
source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true
print_info "等待安装完成..."
sleep 5
else
print_error "下载的文件太小 (${FILE_SIZE} bytes),可能下载不完整"
rm -f "$TEMP_INSTALL_SCRIPT"
return 1
fi
else
print_error "安装脚本下载失败"
return 1
fi
else
print_error "无法下载安装脚本"
return 1
fi
# 验证安装
if [[ $install_result -eq 0 ]] && [[ -d ~/.acme.sh ]] && [[ -f ~/.acme.sh/acme.sh ]]; then
print_success "acme.sh 安装成功"
else
@@ -1463,8 +1565,6 @@ deploy_acme_zerossl() {
echo " - 安装命令退出码: $install_result"
echo " - 目录 ~/.acme.sh 存在: $([ -d ~/.acme.sh ] && echo '是' || echo '否')"
echo " - 文件 ~/.acme.sh/acme.sh 存在: $([ -f ~/.acme.sh/acme.sh ] && echo '是' || echo '否')"
echo " - HOME变量: $HOME"
echo " - 当前用户: $(whoami)"
echo ""
return 1
fi
@@ -1534,32 +1634,65 @@ deploy_acme_zerossl() {
deploy_acme_buypass() {
print_step "使用 acme.sh + Buypass 部署SSL证书..."
# 安装acme.sh
# 安装acme.sh(使用改进的安装逻辑)
if [[ ! -d ~/.acme.sh ]]; then
echo ""
print_info "正在安装 acme.sh..."
# 检测网络环境
# 检测网络环境,选择下载源
if curl -s --connect-timeout 3 https://www.google.com > /dev/null 2>&1; then
# 海外网络
print_info "使用官方源安装..."
curl -fsSL https://get.acme.sh | sh
install_result=$?
INSTALL_URL="https://get.acme.sh"
else
# 中国大陆 - 使用Gitee镜像
print_info "检测到国内网络使用Gitee镜像加速..."
INSTALL_URL="https://gitee.com/neilpang/acme.sh/raw/master/acme.sh"
export ACME_USE_GITEE=1
curl -fsSL https://gitee.com/neilpang/acme.sh/raw/master/acme.sh | sh
install_result=$?
fi
# 重新加载环境变量
source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true
# 改进的安装流程:先下载到临时文件,验证后再执行
TEMP_INSTALL_SCRIPT="/tmp/acme-install-$$.sh"
print_info "正在下载安装脚本..."
# 等待文件系统同步
sleep 2
if curl -fsSL "$INSTALL_URL" -o "$TEMP_INSTALL_SCRIPT"; then
if [[ -f "$TEMP_INSTALL_SCRIPT" ]]; then
FILE_SIZE=$(stat -c%s "$TEMP_INSTALL_SCRIPT" 2>/dev/null || stat -f%z "$TEMP_INSTALL_SCRIPT" 2>/dev/null || echo "0")
# 验证安装是否真正成功(检查目录是否创建)
if [[ $FILE_SIZE -gt 1000 ]]; then
print_success "安装脚本下载成功 (${FILE_SIZE} bytes)"
print_info "验证脚本内容..."
if head -3 "$TEMP_INSTALL_SCRIPT" | grep -q "acme.sh"; then
print_success "脚本内容验证通过"
else
print_warning "脚本内容可能异常,但继续尝试..."
fi
print_info "正在执行安装..."
bash "$TEMP_INSTALL_SCRIPT" --install
install_result=$?
rm -f "$TEMP_INSTALL_SCRIPT"
source ~/.bashrc 2>/dev/null || source ~/.profile 2>/dev/null || true
print_info "等待安装完成..."
sleep 5
else
print_error "下载的文件太小 (${FILE_SIZE} bytes),可能下载不完整"
rm -f "$TEMP_INSTALL_SCRIPT"
return 1
fi
else
print_error "安装脚本下载失败"
return 1
fi
else
print_error "无法下载安装脚本"
return 1
fi
# 验证安装
if [[ $install_result -eq 0 ]] && [[ -d ~/.acme.sh ]] && [[ -f ~/.acme.sh/acme.sh ]]; then
print_success "acme.sh 安装成功"
else
@@ -1569,8 +1702,6 @@ deploy_acme_buypass() {
echo " - 安装命令退出码: $install_result"
echo " - 目录 ~/.acme.sh 存在: $([ -d ~/.acme.sh ] && echo '是' || echo '否')"
echo " - 文件 ~/.acme.sh/acme.sh 存在: $([ -f ~/.acme.sh/acme.sh ] && echo '是' || echo '否')"
echo " - HOME变量: $HOME"
echo " - 当前用户: $(whoami)"
echo ""
return 1
fi