4.4 KiB
4.4 KiB
Nexus 新增宝塔 Session 自动检测/修复记录
日期:2026-07-07 测试部署机:192.168.124.219 项目目录:/opt/nexus-dev-current 分支:audit/security-review 提交:5ac3f56 fix: auto repair btpanel session cleanup ttl
目标
- 新增服务器/新增宝塔自动检测宝塔
/www/server/panel/task.py是否存在if f_time > 3600:的 session 清理硬编码。 - 只在识别到精确可修复模式时自动备份并 patch。
- 一键登录前增加兜底检测/修复,避免已经配置过 API Key 的老服务器继续因为 1 小时清理而刷新掉线。
- 把检测/修复状态保存到
servers.extra_attrs.bt_panel,并在登录 URL 响应 diagnostics 里返回非敏感诊断信息。
修改文件
/opt/nexus-dev-current/server/infrastructure/btpanel/ssh_bootstrap.py/opt/nexus-dev-current/server/infrastructure/btpanel/bootstrap_state.py/opt/nexus-dev-current/server/application/services/btpanel_service.py/opt/nexus-dev-current/tests/test_btpanel_login_url.py/opt/nexus-dev-current/tests/test_btpanel_ssh_bootstrap.py
核心逻辑
新增/绑定宝塔时
ssh_bootstrap_panel() 远程执行 bootstrap 脚本时会:
- 检查
/www/server/panel/task.py。 - 如果已经包含
session_cleanup_timeout = int(public.get_session_timeout() or 86400)且清理条件为if f_time > session_cleanup_timeout:,记录为patched_timeout。 - 如果命中旧模式:
- 备份到
/www/server/panel/task.py.nexus-session-ttl.bak; - 将固定 3600 秒改成读取
public.get_session_timeout(); - 保留原文件权限;
- 先执行 Python compile 和
py_compile.compile(tmp, doraise=True); - 原子替换 task.py;
- 重载宝塔
/etc/init.d/bt reload。
- 备份到
- 如果 task.py 结构不匹配,记录
unknown_task_pattern,不盲改。
一键登录前
BtPanelService.create_login_url() 在生成宝塔一键登录 URL 前会:
- 若服务器已配置宝塔 API,则调用
_ensure_session_cleanup_ttl_for_login()。 - 该检查按缓存节流:
- 成功后 24 小时内不重复修复;
- 失败后 1 小时后可重试。
- 修复失败不会阻断本次一键登录,只会记录 diagnostics 和状态。
新增状态字段
保存到:servers.extra_attrs.bt_panel
session_cleanup_ttl_oksession_cleanup_ttl_patchedsession_cleanup_task_statesession_cleanup_ttl_checked_atsession_cleanup_ttl_last_errorpanel_ssl
session_cleanup_task_state 当前可能值:
patched_timeout:已经修好或本次修好;unknown_task_pattern:task.py 存在,但不是已知可安全 patch 的结构;no_panel:未找到 task.py;error:检查/修复异常。
安全边界
- 不保存、不输出宝塔 tmp_token。
- 不显示 API Key 明文。
- 不自动修改
panel_ssl=0。 - 不自动改
check_client_hash()。 - 不对未知 task.py 结构做模糊替换。
- 修改 task.py 前一定备份,写入前做编译检查,写入使用原子替换。
验证
在测试部署机 /opt/nexus-dev-current 执行:
.venv/bin/python -m py_compile \
server/infrastructure/btpanel/ssh_bootstrap.py \
server/infrastructure/btpanel/bootstrap_state.py \
server/application/services/btpanel_service.py \
tests/test_btpanel_login_url.py \
tests/test_btpanel_ssh_bootstrap.py
.venv/bin/python -m pytest \
tests/test_btpanel_ssh_bootstrap.py \
tests/test_btpanel_login_url.py \
tests/test_btpanel_bootstrap_loop.py \
tests/test_btpanel_login_url_route.py \
tests/test_btpanel_ssh_login.py \
tests/test_btpanel_temp_login_ttl.py -q
结果:
39 passed in 0.61s
测试容器已热更新并重启:
curl http://127.0.0.1:18600/health => ok
nexus-nexus-1 healthy
注意:测试机 docker compose up -d --build nexus 曾因为远端 docker 代理 127.0.0.1:10808 不可达导致 metadata 拉取失败,所以本次测试环境采用 docker cp + docker restart 热更新容器。代码已提交到工作树,后续可在代理可用时重建镜像。
后续发布正式环境建议
正式环境不要 git reset,建议继续采用之前方式:
- 备份正式容器内对应文件;
docker cp本次 3 个后端文件到正式容器;- 容器内
python -m py_compile; - restart 容器;
/health检查;- 抽一台新增/未修复宝塔做一键登录验证,确认 diagnostics 返回
session_cleanup_task_state=patched_timeout。