3x-ui/docs/install-fix-checklist.md
root f5862abc2e feat: add CodeMirror YAML editor for Clash template and fix settings save button bug
- Replace plain textarea with CodeMirror editor (YAML syntax highlighting, line numbers, auto-indent) for Clash subscription template
- Fix confAlerts crash when subClashURI/subURI/subJsonURI is null/undefined (prevented save button from enabling)
- Add yaml.js CodeMirror mode asset
- Include docs and .gitignore cleanup
2026-04-24 16:15:22 +08:00

16 KiB
Raw Blame History

install.sh 修复清单与逐项修复说明

说明

本文基于 docs/install-issue-assessment.md 的分级结果,结合 install.shx-ui.shupdate.sh、service 模板与项目核心配置/启动逻辑的交叉检查,整理出一份可执行的修复清单。

文档目标:

  • 把问题清单转成“可落地的修复项”
  • 标明每项修复是否需要联动改动
  • 提前指出与现有代码约定的冲突点
  • 给出最小可验证的验收方式

使用建议

  • 优先处理 P0 / P1,再处理输入校验、引号和死代码
  • 涉及 service 路径、自定义安装目录、MariaDB 首装流程的项,不建议只改 install.sh
  • 涉及“是否强制 HTTPS”“是否保留默认 admin/admin”的项属于产品行为决策修复前先定策略

一、核心修复项

1. 修复端口占用检测逻辑

  • 对应问题P0-01
  • 涉及文件
    • install.sh
    • x-ui.sh
    • update.sh
  • 修复说明
    • 当前 ss / netstat 分支使用 awk '$4 ~ p {exit 0} END {exit 1}',即使命中也会在 END 阶段返回失败。
    • 应统一改成可靠的布尔判断方式,例如:
      • ss -ltn | awk ... 时使用状态变量控制退出码
      • 或直接用 grep -q
    • 三个脚本里有重复实现,必须一次性同步修改,避免菜单脚本和安装脚本行为不一致。
  • 是否与项目代码冲突:否
  • 是否会改变行为:会,但属于“从错误行为修正为正确行为”
  • 验收点
    • 在端口已被监听时能稳定返回“占用”
    • 在端口空闲时能稳定返回“空闲”
    • 三个脚本的检测结果一致

2. 修复 SSL 失败仍显示成功

  • 对应问题P0-02
  • 涉及文件
    • install.sh
  • 修复说明
    • prompt_and_setup_ssl 返回失败后,当前脚本仍会输出 HTTPS 地址和“SSL 已启用并配置”。
    • 至少要做到:
      • 根据返回值区分“SSL 成功 / SSL 失败”
      • 失败时不要显示成功文案
      • 失败时不要强制输出 https://...
    • 更进一步可以考虑:
      • 失败即中止安装
      • 或允许继续安装但明确标记为“HTTP/未启用 SSL”
  • 是否与项目代码冲突:否
  • 是否会改变行为:会,安装摘要将不再“伪成功”
  • 注意事项
    • 运行时 Web 服务本身支持 HTTP fallback因此此项修复应优先修正文案不要未经确认直接改成“SSL 失败即安装失败”
  • 验收点
    • 证书签发失败时摘要中不再出现“SSL 已启用”
    • 地址协议与实际生效状态一致

3. 修复 ssl_cert_issue 的成功判定方式

  • 对应问题P0-03
  • 涉及文件
    • install.sh
  • 修复说明
    • 现在通过 acme.sh --list | tail -1 推断“本次签发的是哪张证书”,这不可靠。
    • 更合理的修法:
      • ssl_cert_issue() 在成功时直接返回本次域名
      • 或在函数内直接完成域名保存,不依赖外部再去猜
      • 或基于用户输入域名作为唯一可信来源,不再查列表尾项
  • 是否与项目代码冲突:否
  • 是否会改变行为:会,证书成功识别逻辑更严格
  • 验收点
    • 机器上存在多张证书时,脚本仍能准确识别本次域名
    • 不会因为列表最后一项不是当前域名而误写配置

4. 去除默认 admin/admin 安装行为

  • 对应问题P0-04
  • 涉及文件
    • install.sh
  • 关联代码
    • database/db.go
  • 修复说明
    • 当前脚本文案声称“留空自动生成”,实际却回退为 admin/admin
    • 建议修法:
      • 用户名留空时默认 admin 可以接受,但应明确提示
      • 密码留空时必须随机生成
      • 若输入 rd,也应随机生成密码而不是回退默认值
      • 安装完成时明确输出最终用户名/密码
  • 是否与项目代码冲突:否
  • 是否会改变行为:是,默认安装体验会改变
  • 注意事项
    • 核心代码默认种子用户仍是 admin/admin,安装脚本只是覆盖它
    • 因此此项不要求先改 Go 代码,也能落地
  • 验收点
    • 留空安装时不再生成 admin/admin
    • 安装摘要里显示的密码与实际可登录密码一致

5. 重构 MariaDB 首装流程

  • 对应问题P0-05
  • 涉及文件
    • install.sh
  • 关联代码
    • main.go
    • config/config.go
    • web/service/setting.go
  • 修复说明
    • 当前流程是:
      1. 先按默认 SQLite 初始化和写配置
      2. 再把 dbType 改成 MariaDB
      3. 但没有做 SQLite → MariaDB 数据迁移
    • 这会导致“用户输入过的配置不一定落到最终使用的库”。
    • 推荐修法有两种:
      • 方案 A保守修法
        • 首装统一先走 SQLite
        • 若用户选择 MariaDB提示安装完成后执行明确迁移
        • 避免脚本伪装成“已直接落到 MariaDB”
      • 方案 B彻底修法
        • 在项目代码里补一个“无 DB bootstrap 配置写入流程”
        • 先写 settings JSON再按 dbType 初始化对应数据库
    • 如果只改脚本顺序,不改项目代码,风险仍然较高。
  • 是否与项目代码冲突:有耦合,需要联动
  • 是否会改变行为:是,尤其是 MariaDB 首装路径
  • 验收点
    • 首次选择 MariaDB 后,最终实际运行库中存在用户刚设置的账号/端口/路径
    • 不再出现“看似设置成功,实际登录不上”的情况

6. 修复 install_acme() 污染当前目录

  • 对应问题P0-06
  • 涉及文件
    • install.sh
  • 修复说明
    • install_acme() 进入 ~ 后不恢复当前目录,后续若依赖解压目录中的文件会出错。
    • 建议修法:
      • 函数内保存当前目录并在结束前恢复
      • 或彻底改成绝对路径,不依赖当前工作目录
  • 是否与项目代码冲突:否
  • 是否会改变行为:否,属于纯修复
  • 验收点
    • 安装 acme 之后,仍能从解压目录找到 service 文件
    • 安装过程中的后续 cp/cd 行为不再受影响

7. 统一 Arch 的安装路径与 service 路径

  • 对应问题P0-07
  • 涉及文件
    • install.sh
    • x-ui.service.arch
  • 修复说明
    • 当前脚本默认安装到 /usr/local/x-ui,但 Arch service 指向 /usr/lib/x-ui
    • 修法应二选一:
      • 要么 Arch 平台真的安装到 /usr/lib/x-ui
      • 要么修改 Arch service 模板,让它和 xui_folder 保持一致
    • 推荐后者:统一用安装脚本渲染 service 路径,而不是靠固定模板硬编码。
  • 是否与项目代码冲突:否,但与 service 模板强相关
  • 是否会改变行为:会,从“默认可能起不来”变成“可正常启动”
  • 验收点
    • Arch 安装后 systemctl status x-ui 正常
    • service 的 WorkingDirectoryExecStart 指向真实安装目录

8. 给删除安装目录增加安全保护

  • 对应问题P0-08
  • 涉及文件
    • install.sh
    • 建议同步评估 x-ui.sh
  • 修复说明
    • 当前直接 rm -rf ${xui_folder}/,若环境变量异常可能误删危险路径。
    • 建议加以下保护:
      • 变量不能为空
      • 不能是 /
      • 不能是 /usr/usr/local 这类上层目录
      • 路径必须匹配预期模式
      • 统一加引号
  • 是否与项目代码冲突:否
  • 是否会改变行为:否,属于安全兜底
  • 验收点
    • 正常安装目录可删除
    • 危险目录会被拒绝并报错

二、联动修复项

9. 自定义安装目录支持做全链路统一

  • 对应问题P1-01P1-11
  • 涉及文件
    • install.sh
    • x-ui.sh
    • update.sh
    • x-ui.service.debian
    • x-ui.service.rhel
    • x-ui.service.arch
    • x-ui.rc
  • 修复说明
    • 目前只有脚本变量允许覆盖安装目录,但 service 模板与部分流程仍硬编码路径。
    • 修法建议:
      • 统一把 service/init 文件改为模板渲染
      • 所有脚本都以 XUI_MAIN_FOLDER 为唯一事实来源
      • 不再通过 ${xui_folder%/x-ui} 推导工作目录
  • 是否与项目代码冲突:否
  • 是否会改变行为:会,自定义目录将真正可用
  • 验收点
    • 设置 XUI_MAIN_FOLDER安装、升级、菜单、service 启动全部正常

10. 统一证书状态判定逻辑

  • 对应问题P1-07 及相关派生问题
  • 涉及文件
    • install.sh
    • web/web.go
    • web/html/settings.html
  • 修复说明
    • 当前前端和安装脚本在“何时算 HTTPS 启用”上判断过于宽松。
    • 运行时真实逻辑是:只有证书和私钥都能被加载,才会启用 TLS。
    • 修法建议:
      • 安装摘要中:必须 cert + key 都有效才显示 HTTPS
      • 前端跳转逻辑中:不要用 webCertFile || webKeyFile 判定 HTTPS
      • 可选地增加“证书路径存在但加载失败”的状态提示
  • 是否与项目代码冲突:否,是向运行时行为靠拢
  • 是否会改变行为:会,状态显示更严格
  • 验收点
    • 只有 cert/key 成对有效时才显示 HTTPS
    • 前端不会因为只填了一项路径就强跳 HTTPS

11. 同步修复脚本族中的重复问题

  • 对应问题:重复逻辑导致的派生风险
  • 涉及文件
    • install.sh
    • x-ui.sh
    • update.sh
  • 修复说明
    • 多处辅助函数和路径逻辑是复制粘贴的。
    • 推荐修法:
      • 先列出三者重复函数:端口检测、域名/IP 校验、acme 检查、目录变量
      • 同批次修改,避免只修了安装脚本但菜单脚本/更新脚本依旧保留旧 bug
    • 长期建议是提取共享 shell 片段,但短期不一定需要重构。
  • 是否与项目代码冲突:否
  • 是否会改变行为:会,让相关脚本行为一致
  • 验收点
    • 同一类操作在三个脚本中的表现一致

三、需要先做产品决策的修复项

12. 决定 SSL 失败时是否中止安装

  • 对应问题P0-02 的策略层延伸
  • 涉及文件
    • install.sh
    • 间接关联 web/web.go
  • 修复说明
    • 当前脚本文案把 SSL 描述成“必需”,但运行时实际上支持 HTTP。
    • 修复前要先定策略:
      • 策略 ASSL 失败仍允许安装
        • 但必须准确提示“当前为 HTTP”
      • 策略 BSSL 失败即安装失败
        • 真正把 SSL 变成安装前置条件
    • 两种都能实现,但这是产品行为选择,不是单纯 bugfix。
  • 是否与项目代码冲突:否
  • 是否会改变行为:是
  • 验收点
    • 安装流程与产品定义一致
    • 文案、输出地址、最终服务状态三者一致

13. 决定默认凭据策略

  • 对应问题P0-04
  • 涉及文件
    • install.sh
    • 间接关联 database/db.go
  • 修复说明
    • 需要明确项目策略是:
      • 保留默认用户名 admin
      • 默认密码随机
      • 还是用户名、密码都随机
    • 一旦确定,应同步修改:
      • 安装提示
      • 安装完成摘要
      • 相关文档
  • 是否与项目代码冲突:否
  • 是否会改变行为:是
  • 验收点
    • 安装体验符合预期
    • 登录凭据输出准确、可复现

14. 决定是否正式支持“首装直连 MariaDB”

  • 对应问题P0-05
  • 涉及文件
    • install.sh
    • main.go
    • config/config.go
    • web/service/setting.go
  • 修复说明
    • 若确认保留这个能力,建议不要再依赖“先 InitDB 再改 dbType”的间接流程。
    • 更合理的做法是引入正式 bootstrap
      • 先生成 settings JSON
      • 再依据 dbType 初始化数据库
      • 再写用户与面板基础配置
    • 若短期不想改 Go 代码则建议安装脚本暂时不要把“MariaDB 首装直连”包装成已完整支持。
  • 是否与项目代码冲突:有实现耦合
  • 是否会改变行为:是
  • 验收点
    • 首装 MariaDB 路径不再依赖 SQLite 中间态

四、低风险可批量修复项

15. 给关键命令补错误检查

  • 对应问题P1-02P1-03P1-04
  • 涉及文件
    • install.sh
  • 修复说明
    • tarcdconfig_after_install、依赖安装等关键步骤都应显式校验返回值。
    • 建议统一模式:
      • 关键命令失败立即退出
      • 输出明确错误原因
  • 是否与项目代码冲突:否
  • 是否会改变行为:会,更早失败、更容易定位问题
  • 验收点
    • 任一关键步骤失败时,脚本立即停止并给出准确信息

16. 修复路径和变量未加引号

  • 对应问题P2-18
  • 涉及文件
    • install.sh
    • x-ui.sh
    • update.sh
  • 修复说明
    • 所有路径、URL、证书目录、安装目录、环境变量路径都应统一加引号。
    • 尤其是:
      • rm -rf
      • cp
      • mv
      • chmod
      • 执行 ${xui_folder}/x-ui
  • 是否与项目代码冲突:否
  • 是否会改变行为:通常不会,只提升稳健性
  • 验收点
    • 自定义目录、带空格路径时脚本仍工作正常

17. 修复手动端口输入默认值与数字校验

  • 对应问题P2-05P2-06P2-07
  • 涉及文件
    • install.sh
  • 修复说明
    • 用户回车时应自然使用默认端口,而不是走“无效输入”
    • 所有端口输入统一做:
      • 去空格
      • 数字校验
      • 1-65535 范围校验
      • 端口占用校验
  • 是否与项目代码冲突:否
  • 是否会改变行为:会,交互更合理
  • 验收点
    • 空输入能正确落默认值
    • 非数字输入会被拒绝
    • 冲突端口会被识别

18. 修复公网 IP 获取失败后的交互路径

  • 对应问题P2-12
  • 涉及文件
    • install.sh
  • 修复说明
    • 当前 server_ip 获取失败后IP 证书路径依然可能被当作默认路径。
    • 建议修法:
      • 获取失败时提示用户手动输入 IPv4
      • 或自动把默认 SSL 选项切到域名/自定义证书
      • 至少不能继续伪装“默认可走 IP 证书”
  • 是否与项目代码冲突:否
  • 是否会改变行为:会,失败路径更明确
  • 验收点
    • IP 获取失败时不会再生成空主机名 URL

19. Cloudflare API Key 改为静默输入并清理环境变量

  • 对应问题P2-13P2-14
  • 涉及文件
    • install.sh
  • 修复说明
    • API Key 应使用静默输入
    • 导出环境变量后应在流程结束时 unset
    • 域名也应走 is_domain 校验
  • 是否与项目代码冲突:否
  • 是否会改变行为:会,更安全
  • 验收点
    • 终端不会明文回显 API Key
    • 函数结束后环境变量不残留

20. 清理死代码与误导注释

  • 对应问题P3-01P3-02P3-03P3-05P3-06P3-07P3-08
  • 涉及文件
    • install.sh
  • 修复说明
    • 删除未使用变量与未接入函数
    • 修正不准确注释和提示文案
    • 调整 bash 风格问题(如 == 0-eq 0 这类可读性优化)
  • 是否与项目代码冲突:否
  • 是否会改变行为:通常不会
  • 验收点
    • 代码更容易维护,输出文案与实际逻辑一致

五、建议执行顺序

第一批:立即修

  • 修复端口检测
  • 修复 SSL 伪成功
  • 修复 install_acme 目录污染
  • 修复 Arch service 路径
  • 修复危险删除逻辑

第二批:联动修

  • 自定义安装目录全链路支持
  • 三个 shell 脚本重复逻辑同步修复
  • 证书状态判定统一到运行时真实行为

第三批:策略确认后再修

  • SSL 失败是否中止安装
  • 默认凭据策略
  • MariaDB 首装是否正式支持

第四批:批量清理

  • 输入校验
  • 错误检查
  • 引号与安全性
  • 死代码与注释

六、最小验收清单

  • install.shx-ui.shupdate.sh 的端口检测结果一致
  • 证书失败时安装摘要不再伪装 HTTPS 成功
  • Arch / Debian / RHEL / Alpine 的 service/init 路径与实际安装目录一致
  • 自定义 XUI_MAIN_FOLDER 后,安装、升级、菜单脚本都能正常工作
  • 选择 MariaDB 时,最终实际使用的数据库中存在用户刚输入的配置
  • 密码留空不再回退 admin/admin
  • Cloudflare API Key 不再明文输入
  • 公网 IP 获取失败时,默认流程不会给出空地址或错误 HTTPS 地址