fix: 修复SSL证书部署的两个关键问题

问题1:acme.sh证书安装时nginx reload失败
- 错误:nginx.service is not active, cannot reload
- 原因:证书安装时nginx服务未运行
- 解决:
  1. 在安装证书前检查并启动nginx服务
  2. 移除--reloadcmd参数,改为手动reload
  3. 兼容systemctl和直接nginx命令两种方式
  4. 兼容宝塔面板的nginx路径

问题2:Certbot安装/运行时urllib3依赖冲突
- 错误:ImportError: cannot import name 'appengine' from 'urllib3.contrib'
- 原因:系统的python3-urllib3版本与certbot不兼容
- 解决:
  1. 安装certbot前移除冲突的python3-urllib3包
  2. 添加已安装certbot的依赖修复逻辑
  3. 应用到apt/yum/dnf等所有包管理器
  4. 提供详细的错误提示和修复建议

技术改进:
- acme.sh安装证书更可靠(分离安装和reload步骤)
- Certbot依赖检测更完善(检测并修复依赖冲突)
- 错误处理更友好(提示用户尝试其他方案)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
WanWanYun
2025-11-13 15:09:25 +08:00
parent ab577931c3
commit 8b9af536c7

View File

@@ -1285,17 +1285,25 @@ deploy_certbot() {
print_success "Certbot (snap版) 安装成功" print_success "Certbot (snap版) 安装成功"
else else
print_warning "snap安装失败尝试apt安装..." print_warning "snap安装失败尝试apt安装..."
# 修复urllib3依赖问题
apt-get remove -y python3-urllib3 2>/dev/null || true
apt-get install -y certbot python3-certbot-nginx apt-get install -y certbot python3-certbot-nginx
fi fi
else else
print_info "snap不可用使用apt安装..." print_info "snap不可用使用apt安装..."
# 修复urllib3依赖问题
apt-get remove -y python3-urllib3 2>/dev/null || true
apt-get install -y certbot python3-certbot-nginx apt-get install -y certbot python3-certbot-nginx
fi fi
;; ;;
yum) yum)
# 修复urllib3依赖问题
yum remove -y python3-urllib3 2>/dev/null || true
yum install -y certbot python3-certbot-nginx yum install -y certbot python3-certbot-nginx
;; ;;
dnf) dnf)
# 修复urllib3依赖问题
dnf remove -y python3-urllib3 2>/dev/null || true
dnf install -y certbot python3-certbot-nginx dnf install -y certbot python3-certbot-nginx
;; ;;
zypper) zypper)
@@ -1312,6 +1320,28 @@ deploy_certbot() {
print_success "Certbot 已安装: $(certbot --version 2>&1 | head -1)" print_success "Certbot 已安装: $(certbot --version 2>&1 | head -1)"
fi fi
# 修复已安装certbot的urllib3依赖冲突
if ! certbot --version &> /dev/null; then
print_warning "检测到Certbot依赖问题正在修复..."
case $PKG_MANAGER in
apt)
apt-get remove -y python3-urllib3 2>/dev/null || true
apt-get install --reinstall -y certbot python3-certbot-nginx
;;
yum|dnf)
$PKG_MANAGER remove -y python3-urllib3 2>/dev/null || true
$PKG_MANAGER reinstall -y certbot python3-certbot-nginx
;;
esac
# 再次验证
if ! certbot --version &> /dev/null; then
print_error "Certbot依赖修复失败建议尝试其他SSL方案"
return 1
fi
print_success "Certbot依赖已修复"
fi
# 申请证书使用webroot模式不自动修改Nginx配置 # 申请证书使用webroot模式不自动修改Nginx配置
echo "" echo ""
print_info "正在申请 Let's Encrypt 证书..." print_info "正在申请 Let's Encrypt 证书..."
@@ -1481,11 +1511,29 @@ deploy_acme_letsencrypt() {
fi fi
mkdir -p /etc/nginx/ssl mkdir -p /etc/nginx/ssl
# 确保nginx服务已启动证书安装时需要reload
if ! systemctl is-active --quiet nginx 2>/dev/null && ! pgrep -x nginx > /dev/null 2>&1; then
print_warning "Nginx未运行正在启动..."
systemctl start nginx 2>/dev/null || /www/server/nginx/sbin/nginx 2>/dev/null || true
sleep 2
fi
# 先不带reload命令安装证书避免nginx未启动导致失败
if ~/.acme.sh/acme.sh --install-cert -d "$DOMAIN" \ if ~/.acme.sh/acme.sh --install-cert -d "$DOMAIN" \
--key-file /etc/nginx/ssl/${DOMAIN}.key \ --key-file /etc/nginx/ssl/${DOMAIN}.key \
--fullchain-file /etc/nginx/ssl/${DOMAIN}.crt \ --fullchain-file /etc/nginx/ssl/${DOMAIN}.crt; then
--reloadcmd "systemctl reload nginx"; then print_success "证书文件已安装到: /etc/nginx/ssl/"
print_success "证书安装成功"
# 手动reload nginx
if systemctl is-active --quiet nginx 2>/dev/null; then
systemctl reload nginx && print_success "Nginx配置已重载"
elif pgrep -x nginx > /dev/null; then
nginx -s reload && print_success "Nginx配置已重载"
else
print_warning "Nginx未运行将在后续步骤启动"
fi
return 0 return 0
else else
print_error "证书安装失败" print_error "证书安装失败"
@@ -1613,11 +1661,29 @@ deploy_acme_zerossl() {
fi fi
mkdir -p /etc/nginx/ssl mkdir -p /etc/nginx/ssl
# 确保nginx服务已启动证书安装时需要reload
if ! systemctl is-active --quiet nginx 2>/dev/null && ! pgrep -x nginx > /dev/null 2>&1; then
print_warning "Nginx未运行正在启动..."
systemctl start nginx 2>/dev/null || /www/server/nginx/sbin/nginx 2>/dev/null || true
sleep 2
fi
# 先不带reload命令安装证书避免nginx未启动导致失败
if ~/.acme.sh/acme.sh --install-cert -d "$DOMAIN" \ if ~/.acme.sh/acme.sh --install-cert -d "$DOMAIN" \
--key-file /etc/nginx/ssl/${DOMAIN}.key \ --key-file /etc/nginx/ssl/${DOMAIN}.key \
--fullchain-file /etc/nginx/ssl/${DOMAIN}.crt \ --fullchain-file /etc/nginx/ssl/${DOMAIN}.crt; then
--reloadcmd "systemctl reload nginx"; then print_success "证书文件已安装到: /etc/nginx/ssl/"
print_success "证书安装成功"
# 手动reload nginx
if systemctl is-active --quiet nginx 2>/dev/null; then
systemctl reload nginx && print_success "Nginx配置已重载"
elif pgrep -x nginx > /dev/null; then
nginx -s reload && print_success "Nginx配置已重载"
else
print_warning "Nginx未运行将在后续步骤启动"
fi
return 0 return 0
else else
print_error "证书安装失败" print_error "证书安装失败"
@@ -1745,11 +1811,29 @@ deploy_acme_buypass() {
fi fi
mkdir -p /etc/nginx/ssl mkdir -p /etc/nginx/ssl
# 确保nginx服务已启动证书安装时需要reload
if ! systemctl is-active --quiet nginx 2>/dev/null && ! pgrep -x nginx > /dev/null 2>&1; then
print_warning "Nginx未运行正在启动..."
systemctl start nginx 2>/dev/null || /www/server/nginx/sbin/nginx 2>/dev/null || true
sleep 2
fi
# 先不带reload命令安装证书避免nginx未启动导致失败
if ~/.acme.sh/acme.sh --install-cert -d "$DOMAIN" \ if ~/.acme.sh/acme.sh --install-cert -d "$DOMAIN" \
--key-file /etc/nginx/ssl/${DOMAIN}.key \ --key-file /etc/nginx/ssl/${DOMAIN}.key \
--fullchain-file /etc/nginx/ssl/${DOMAIN}.crt \ --fullchain-file /etc/nginx/ssl/${DOMAIN}.crt; then
--reloadcmd "systemctl reload nginx"; then print_success "证书文件已安装到: /etc/nginx/ssl/"
print_success "证书安装成功"
# 手动reload nginx
if systemctl is-active --quiet nginx 2>/dev/null; then
systemctl reload nginx && print_success "Nginx配置已重载"
elif pgrep -x nginx > /dev/null; then
nginx -s reload && print_success "Nginx配置已重载"
else
print_warning "Nginx未运行将在后续步骤启动"
fi
return 0 return 0
else else
print_error "证书安装失败" print_error "证书安装失败"