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

466 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# install.sh 修复清单与逐项修复说明
## 说明
本文基于 `docs/install-issue-assessment.md` 的分级结果,结合 `install.sh`、`x-ui.sh`、`update.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 的 `WorkingDirectory``ExecStart` 指向真实安装目录
### 8. 给删除安装目录增加安全保护
- **对应问题**`P0-08`
- **涉及文件**
- `install.sh`
- 建议同步评估 `x-ui.sh`
- **修复说明**
- 当前直接 `rm -rf ${xui_folder}/`,若环境变量异常可能误删危险路径。
- 建议加以下保护:
- 变量不能为空
- 不能是 `/`
- 不能是 `/usr`、`/usr/local` 这类上层目录
- 路径必须匹配预期模式
- 统一加引号
- **是否与项目代码冲突**:否
- **是否会改变行为**:否,属于安全兜底
- **验收点**
- 正常安装目录可删除
- 危险目录会被拒绝并报错
---
## 二、联动修复项
### 9. 自定义安装目录支持做全链路统一
- **对应问题**`P1-01`、`P1-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-02`、`P1-03`、`P1-04`
- **涉及文件**
- `install.sh`
- **修复说明**
- `tar`、`cd`、`config_after_install`、依赖安装等关键步骤都应显式校验返回值。
- 建议统一模式:
- 关键命令失败立即退出
- 输出明确错误原因
- **是否与项目代码冲突**:否
- **是否会改变行为**:会,更早失败、更容易定位问题
- **验收点**
- 任一关键步骤失败时,脚本立即停止并给出准确信息
### 16. 修复路径和变量未加引号
- **对应问题**`P2-18`
- **涉及文件**
- `install.sh`
- `x-ui.sh`
- `update.sh`
- **修复说明**
- 所有路径、URL、证书目录、安装目录、环境变量路径都应统一加引号。
- 尤其是:
- `rm -rf`
- `cp`
- `mv`
- `chmod`
- 执行 `${xui_folder}/x-ui`
- **是否与项目代码冲突**:否
- **是否会改变行为**:通常不会,只提升稳健性
- **验收点**
- 自定义目录、带空格路径时脚本仍工作正常
### 17. 修复手动端口输入默认值与数字校验
- **对应问题**`P2-05`、`P2-06`、`P2-07`
- **涉及文件**
- `install.sh`
- **修复说明**
- 用户回车时应自然使用默认端口,而不是走“无效输入”
- 所有端口输入统一做:
- 去空格
- 数字校验
- 1-65535 范围校验
- 端口占用校验
- **是否与项目代码冲突**:否
- **是否会改变行为**:会,交互更合理
- **验收点**
- 空输入能正确落默认值
- 非数字输入会被拒绝
- 冲突端口会被识别
### 18. 修复公网 IP 获取失败后的交互路径
- **对应问题**`P2-12`
- **涉及文件**
- `install.sh`
- **修复说明**
- 当前 `server_ip` 获取失败后IP 证书路径依然可能被当作默认路径。
- 建议修法:
- 获取失败时提示用户手动输入 IPv4
- 或自动把默认 SSL 选项切到域名/自定义证书
- 至少不能继续伪装“默认可走 IP 证书”
- **是否与项目代码冲突**:否
- **是否会改变行为**:会,失败路径更明确
- **验收点**
- IP 获取失败时不会再生成空主机名 URL
### 19. Cloudflare API Key 改为静默输入并清理环境变量
- **对应问题**`P2-13`、`P2-14`
- **涉及文件**
- `install.sh`
- **修复说明**
- API Key 应使用静默输入
- 导出环境变量后应在流程结束时 `unset`
- 域名也应走 `is_domain` 校验
- **是否与项目代码冲突**:否
- **是否会改变行为**:会,更安全
- **验收点**
- 终端不会明文回显 API Key
- 函数结束后环境变量不残留
### 20. 清理死代码与误导注释
- **对应问题**`P3-01`、`P3-02`、`P3-03`、`P3-05`、`P3-06`、`P3-07`、`P3-08`
- **涉及文件**
- `install.sh`
- **修复说明**
- 删除未使用变量与未接入函数
- 修正不准确注释和提示文案
- 调整 bash 风格问题(如 `== 0``-eq 0` 这类可读性优化)
- **是否与项目代码冲突**:否
- **是否会改变行为**:通常不会
- **验收点**
- 代码更容易维护,输出文案与实际逻辑一致
---
## 五、建议执行顺序
### 第一批:立即修
- 修复端口检测
- 修复 SSL 伪成功
- 修复 `install_acme` 目录污染
- 修复 Arch service 路径
- 修复危险删除逻辑
### 第二批:联动修
- 自定义安装目录全链路支持
- 三个 shell 脚本重复逻辑同步修复
- 证书状态判定统一到运行时真实行为
### 第三批:策略确认后再修
- SSL 失败是否中止安装
- 默认凭据策略
- MariaDB 首装是否正式支持
### 第四批:批量清理
- 输入校验
- 错误检查
- 引号与安全性
- 死代码与注释
---
## 六、最小验收清单
- [ ] `install.sh`、`x-ui.sh`、`update.sh` 的端口检测结果一致
- [ ] 证书失败时安装摘要不再伪装 HTTPS 成功
- [ ] Arch / Debian / RHEL / Alpine 的 service/init 路径与实际安装目录一致
- [ ] 自定义 `XUI_MAIN_FOLDER` 后,安装、升级、菜单脚本都能正常工作
- [ ] 选择 MariaDB 时,最终实际使用的数据库中存在用户刚输入的配置
- [ ] 密码留空不再回退 `admin/admin`
- [ ] Cloudflare API Key 不再明文输入
- [ ] 公网 IP 获取失败时,默认流程不会给出空地址或错误 HTTPS 地址