宝塔用户_nbcllg 发表于 2026-8-12 17:48:24

【Bug 反馈】宝塔面板 13.0.0 面板SSL证书监控任务导致面板...

# 【Bug 反馈】宝塔面板 13.0.0 面板SSL证书监控任务导致面板无限 reload 循环(Web 终端持续刷屏)

- **面板版本**:13.0.0
- **系统环境**:Ubuntu 24.04.4 LTS / 宝塔 Linux 面板
- **问题类型**:面板进程反复重启 / Web 终端持续刷屏 / reload 死循环

---

## 一、问题现象

面板 Web 终端持续无限打印以下内容(每 3~5 秒重复一次,永不停止):

```
Last login: Wed Jul 8 00:17:23 +0800 2026 from 119.123.43.208
The current terminal create by BT-Panel.
root@instance-dobacobh:~# Last login: ...
```

伴随现象:
1. `/www/server/panel/logs/terminal.log` 每 3~5 秒记录一次 `认证成功,正在构建会话通道`
2. `/www/server/panel/logs/task.log` 反复出现 `面板服务: reload`(本机已累计 **40169 次**,从 2026-03-29 开始,持续至今 4 个多月)
3. 面板主进程(BT-Panel)每 2~4 秒被重启一次,PID 不断变化

## 二、根因分析

完整触发链:

```
面板证书为 Let's Encrypt(即将到期)
→ BT-Task 启动时执行"面板SSL证书监控"任务(script/panel_ssl_task.py)
→ 证书夹 /www/server/panel/vhost/cert/ 中存在 LE 证书
→ 脚本判断 ssl['not_after'] > cert_info['notAfter'] 恒为真(字符串比较 bug)
→ 执行"替换证书"并写入 /www/server/panel/data/reload.pl
→ BT-Task 检测到 reload.pl,执行"面板服务: reload"
→ 面板进程被 kill 重启
→ 面板启动后再次执行 SSL 监控任务 → 又写 reload.pl → 无限循环
```

**关键代码**(`/www/server/panel/script/panel_ssl_task.py`):

```python
for ssl in ssl_list:
    info = ssl["info"]
    if info['issuer'] in ["R10", "Let's Encrypt", "R8", "R11", "R5", "R3"] or info.get("issuer_O", "") == "Let's Encrypt":
      if ssl['dns'] == and ssl['not_after'] > today and ssl['not_after'] > cert_info['notAfter']:
            print("已存在有效的IP证书,无需重复申请")
            cert_pem = public.readFile(ssl['path'] + '/fullchain.pem')
            key_pem = public.readFile(ssl['path'] + '/privkey.pem')
            if cert_pem and key_pem:
                print("替换证书")
                public.writeFile('/www/server/panel/ssl/certificate.pem', cert_pem)
                public.writeFile('/www/server/panel/ssl/privateKey.pem', key_pem)
                public.writeFile('/www/server/panel/data/reload.pl', "1")   # ← 触发 reload
                exit(0)
```

**Bug 所在**:`ssl['not_after']` 与 `cert_info['notAfter']` 是**不同格式的字符串**(例如 `"2026-08-14"` vs `"2026-08-14 21:52:48"`),直接做字符串比较时 `"2026-08-14" > "2026-08-14 21:52:48"` **永远为真**(字符串前缀相同,短的更小)。因此只要证书夹中存在任何一张 LE 证书(哪怕是和面板当前证书**同一张**),每次面板启动都会进入"替换证书"分支并写 reload.pl,造成死循环。

已实测验证:证书夹 `/www/server/panel/vhost/cert/120.48.105.1_80/fullchain.pem` 与面板当前证书 `/www/server/panel/ssl/certificate.pem` 为**同一张证书**(notAfter 均为 `Aug 14 21:52:48 2026 GMT`),手动执行 `panel_ssl_task.py` 依然输出 `替换证书` 并创建 `reload.pl`。

## 三、复现步骤

1. 面板开启面板 SSL,使用 Let's Encrypt 签发的证书
2. 证书夹(`/www/server/panel/vhost/cert/`)中存在同一张 LE 证书(例如通过面板申请过 IP 证书)
3. 重启面板或等 BT-Task 启动,观察 `task.log` 出现循环的 `面板服务: reload`,Web 终端开始刷屏

## 四、修复建议(官方参考)

1. **日期比较改为日期对象**:使用 `datetime.strptime` 解析后比较,避免字符串格式不一致导致的恒真判断
2. **替换前比对证书内容**:`cert_pem` 与当前 `certificate.pem` 内容相同时,直接 `exit(0)`,不写 reload.pl
3. 证书夹与面板当前证书为同一张时,跳过"替换证书"逻辑

## 五、临时修复(已在生产环境验证有效)

在 `panel_ssl_task.py` 的"替换证书"分支前增加证书内容比对保护:

```python
if cert_pem and key_pem:
    current_cert = public.readFile('/www/server/panel/ssl/certificate.pem')
    if current_cert and current_cert.strip() == cert_pem.strip():
      print("证书未变化,无需替换,跳过")
      exit(0)
    print("替换证书")
    public.writeFile('/www/server/panel/ssl/certificate.pem', cert_pem)
    public.writeFile('/www/server/panel/ssl/privateKey.pem', key_pem)
    public.writeFile('/www/server/panel/data/reload.pl', "1")
    exit(0)
```

修复后效果(已验证 30 分钟无复发):
- `task.log` 中 `面板服务: reload` 计数停止增长
- 面板进程 PID 稳定不再重启
- `terminal.log` 不再产生新的会话重建记录
- Web 终端刷屏消失

---

**发帖渠道**:宝塔官方论坛 Bug 提交版块 → https://www.bt.cn/bbs/forum-39-1.html


页: [1]
查看完整版本: 【Bug 反馈】宝塔面板 13.0.0 面板SSL证书监控任务导致面板...