3x-ui/docs/install-issue-assessment.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

13 KiB
Raw Blame History

install.sh 问题评估与分级

说明

本文对 install.sh 及其直接依赖的服务文件进行静态审查,输出逻辑问题、潜在 Bug 与风险分级。

  • 审查对象:install.shx-ui.service.archx-ui.service.debianx-ui.service.rhelx-ui.rc
  • 审查方式:静态阅读 + bash -n install.sh
  • 结论范围:以脚本逻辑为主,不包含联网下载内容真实性、外部服务可用性与目标主机现场状态

分级标准

级别 含义
P0 / 致命 高概率导致安装结果错误、服务不可用、错误安全结论、数据错写或危险操作
P1 / 高 在常见环境下容易触发,导致功能失败、行为不一致或明显错误
P2 / 中 不是每次触发,但会造成兼容性、稳健性、可维护性或边界行为问题
P3 / 低 风险较低,主要是误导、死代码、风格不一致或隐含维护成本

总览

级别 数量 重点
P0 / 致命 8 端口检测失效、SSL 失败仍报成功、MariaDB 新装数据错位、目录漂移
P1 / 高 12 自定义目录不完整支持、安装失败继续、弱口令、服务路径错误
P2 / 中 18 输入校验不足、平台兼容性差、下载/解析脆弱、引号缺失
P3 / 低 8 死代码、注释偏差、提示文案不准确、维护性问题

P0 / 致命

ID 位置 问题 影响 建议
P0-01 install.sh:63, install.sh:67 is_port_in_use()awk ... END {exit 1} 覆盖前面的成功退出码,导致 ss/netstat 分支几乎总返回“端口未占用” 端口冲突检测失效ACME 独立监听端口选择可能错误,安装过程可能与现有服务抢端口 改为纯 grep/ss 判断,或让 awk 使用状态变量并在 END 中按变量返回
P0-02 install.sh:955, install.sh:966, install.sh:969 SSL 配置函数失败后,安装摘要仍打印 HTTPS 地址和“SSL 已启用并配置” 用户被误导为已启用 HTTPS可能错误暴露面板 必须检查 prompt_and_setup_ssl 返回值,失败时终止安装摘要或明确显示失败
P0-03 install.sh:587, install.sh:589 ssl_cert_issue() 返回值未检查,且用 `acme.sh --list tail -1` 取最后一张证书推断本次签发结果 可能把旧证书/无关证书当成本次成功结果写入面板域名
P0-04 install.sh:859, install.sh:863, install.sh:867, install.sh:869 提示称“留空或 rd 自动生成”,实际用户名/密码默认是 admin/admin 新装面板默认弱口令,安全风险极高 留空时应真正随机生成密码,用户名至少提示确认
P0-05 install.sh:890, install.sh:914-920, install.sh:991 新装流程先按默认 SQLite 写面板配置,再切换 dbType=mariadb,但没有执行 SQLite→MariaDB 数据迁移 最终服务连接 MariaDB 后,用户刚设置的账号/端口等可能不在实际使用库里 先确定数据库类型,再初始化与写配置;若从 SQLite 切 MariaDB必须执行显式迁移
P0-06 install.sh:157, install.sh:1106, install.sh:1135-1176 install_acme() 进入家目录后不恢复;config_after_install() 里一旦调用它,会污染后续当前工作目录 可能找不到解压包中的 service 文件,导致安装行为与预期不一致 在函数内保存并恢复目录,或完全使用绝对路径
P0-07 x-ui.service.arch:10-11, install.sh:11, install.sh:1135-1159 Arch 服务文件硬编码 /usr/lib/x-ui,而脚本默认安装到 /usr/local/x-ui Arch 系统默认安装后服务大概率无法启动 安装时模板渲染 ExecStart/WorkingDirectory,不要硬编码
P0-08 install.sh:1078-1084 依赖环境变量的目录删除缺乏安全防护,直接 rm -rf ${xui_folder}/ XUI_MAIN_FOLDER 被误设,可能删除错误目录 删除前校验路径非空、非根目录、符合预期前缀,并统一加引号

P1 / 高

ID 位置 问题 影响 建议
P1-01 install.sh:1041 ${xui_folder%/x-ui} 推导工作目录,隐式假设安装目录以 /x-ui 结尾 自定义目录时下载/解压位置可能错误 单独定义工作目录,不要从安装目录字符串裁剪推导
P1-02 install.sh:1088-1091 解压与 cd x-ui 不检查失败 后续 chmod、复制 service、配置命令可能在错误目录执行 每一步关键文件操作都要显式检查退出码
P1-03 install.sh:1106 config_after_install 失败后仍继续安装 service 并启动 配置失败被掩盖,最终系统状态不可预测 将其纳入主流程错误链,失败立即退出
P1-04 install.sh:76-104, install.sh:1232-1234 install_base() 失败后脚本仍继续执行 缺依赖状态下继续安装,错误位置后移且更难排查 主流程必须检查基础依赖安装结果
P1-05 install.sh:1071, install.sh:1176-1188 指定版本安装时,管理脚本和 fallback service 仍从 main 分支下载 脚本/服务文件与二进制版本不匹配,可能出现不兼容 统一按所选 tag 下载同版本配套文件
P1-06 install.sh:1048, install.sh:1065, install.sh:1071, install.sh:1180-1186 多处强制 curl -4 IPv6-only 主机无法安装或更新 优先正常双栈请求,失败后再回退到 -4
P1-07 install.sh:981-988 已有安装路径中,只要 cert 字段非空就认定已配置 SSL并打印 HTTPS 地址 可能在没有有效证书/私钥时误导用户 同时校验 certkey、文件存在性和可读性
P1-08 install.sh:429-435 证书重复判断只比较 acme.sh --list 最后一条记录 已有当前域名证书时仍可能重复签发 遍历列表精确匹配域名,或直接查询目标证书目录
P1-09 install.sh:384-386 IP 证书流程中,x-ui cert 失败只告警不失败,仍打印“安装并配置成功” 证书文件虽存在,但面板未实际启用证书 写入路径失败应判定整体失败
P1-10 install.sh:611-618, install.sh:623-625 IP 证书模式停止面板后,失败路径没有统一保证服务恢复 安装中断后面板可能保持停止状态 使用 trap 或统一清理/恢复逻辑
P1-11 install.sh:1137-1203, x-ui.service.debian:10-11, x-ui.service.rhel:10-11, x-ui.rc:3, x-ui.rc:12 虽允许 XUI_MAIN_FOLDER 覆盖,但 service/init 模板大量硬编码 /usr/local/x-ui 自定义安装目录时服务启动失败 安装时根据变量生成 service/init 文件
P1-12 install.sh:994-1015 tr/grep/sed 解析 GitHub Releases JSON逻辑脆弱 API 结构变化、字段顺序变化、错误响应时容易取错版本 使用 jq,或服务端返回最小化 API 请求并严格校验 JSON

P2 / 中

ID 位置 问题 影响 建议
P2-01 install.sh:158 `curl ... sh缺少pipefail`,下载失败时可能误报 acme 安装成功 安装状态不可信
P2-02 install.sh:177, install.sh:249, install.sh:396, install.sh:732 command -v ~/.acme.sh/acme.sh 检查路径式命令,可用但不规范 兼容性与可读性较差 直接使用 [ -x ~/.acme.sh/acme.sh ]
P2-03 install.sh:193, install.sh:321, install.sh:463, install.sh:743 设置默认 CA 的命令结果多数未检查 前置动作失败时后续错误定位困难 对关键前置步骤逐一校验
P2-04 install.sh:263-266, install.sh:46-50 IPv4/IPv6 校验过于宽松IPv4 不校验每段范围IPv6 只看是否含 : 非法地址可能进入证书流程 使用更严格的地址校验函数
P2-05 install.sh:451-455 手动 SSL 端口输入为空时不会自然采用默认值,而是走“无效输入”分支 交互体验与提示不一致 WebPort="${WebPort:-80}" 再校验
P2-06 install.sh:452 手动 SSL 端口校验未先判断是否纯数字 异常输入由 shell 算术比较隐式处理,不稳健 先正则校验再做范围比较
P2-07 install.sh:881-888 面板端口输入没有有效校验,也不检测占用 可能写入非法端口或冲突端口 校验数字范围并复用端口占用检测
P2-08 install.sh:886 随机端口不检查是否已被占用 启动服务时可能冲突 生成后循环检测空闲端口
P2-09 install.sh:890-897 只验证端口写入成功,不验证用户名、密码、webBasePath 是否确实写入 配置失败可能部分隐藏 对关键配置项逐项校验
P2-10 install.sh:899-920 MariaDB 连接信息读取与写入缺少完整校验,账号/密码/库名可以为空 后续数据库初始化失败 按数据库类型做必填校验与连通性预检查
P2-11 install.sh:929-945 worker 仅校验 dbType=mariadb,不校验 MariaDB 是否可连接 worker 模式可能被写入无效配置 在设置前做配置与连接校验
P2-12 install.sh:846-855, install.sh:955 获取公网 IP 失败后不提示手动输入IP 证书默认路径会直接失败 默认交互路径容易走向失败 IP 获取失败时要求用户手输或默认跳过 IP 证书
P2-13 install.sh:707-729 Cloudflare 域名未用 is_domain 校验API Key 非静默输入 容易误输,且敏感信息暴露在终端 域名校验 + read -rsp 输入密钥
P2-14 install.sh:751-752 Cloudflare 凭证 export 后未清理 后续子进程可见环境变量 完成后 unset CF_Key CF_Email
P2-15 install.sh:491 允许用户输入任意 reloadcmd,续期时将以高权限执行 误操作或恶意输入可能造成风险 至少明确安全提示,并对常见场景提供模板而非完全任意命令
P2-16 install.sh:91-92 Arch 依赖安装执行两次 pacman -Syu,且第一次无 --noconfirm 交互阻塞、重复更新、耗时增加 合并为一次清晰的安装命令
P2-17 install.sh:1088-1100 ARM 分支先重命名 bin/xray-linux-$(arch),后面又对原文件名 chmod 可能输出错误信息并污染日志 重命名后按最终文件名处理权限
P2-18 install.sh:1048, install.sh:1065, install.sh:1071 等多处 路径、URL、命令参数大量未加引号 自定义目录、异常字符或空格路径下行为不稳定 统一为变量引用加引号

P3 / 低

ID 位置 问题 影响 建议
P3-01 install.sh:9 cur_dir 未使用 增加噪音 删除死代码
P3-02 install.sh:168-236 setup_ssl_certificate() 未被调用,且参数 server_ipexisting_portexisting_webBasePath 未使用 阅读成本高,容易误导维护者 删除死函数或接入统一 SSL 流程
P3-03 install.sh:52-54 is_ip() 未被调用 维护噪音 删除或实际复用
P3-04 install.sh:39 不支持架构时删除当前 install.sh 行为危险且无必要 直接报错退出,不做文件删除
P3-05 install.sh:578 注释“非 1、3、4 默认为 2”表述不完整 容易造成维护误解 注释改为“除 1/3/4 外均视为 2”
P3-06 install.sh:827-832 “全新安装”的判定只看两个文件是否存在,注释与语义不够精确 可读性一般 把注释改成“基于配置/数据库文件存在性判断”
P3-07 install.sh:1044 [ $# == 0 ] 属于 bash 风格写法,可运行但不如 -eq 清晰 风格一致性较差 改用 [ $# -eq 0 ]
P3-08 install.sh:1234 install_x-ui $1 未加引号 边界输入下会参数拆分 改为 install_x-ui "$1"

优先修复建议

建议按以下顺序修复:

  1. 先修 P0-01P0-02P0-05P0-06P0-07
  2. 再修 P1-01P1-03P1-05P1-11
  3. 然后补齐输入校验、错误处理和引号问题
  4. 最后清理死代码、注释和交互文案

建议的验收点

  • 端口占用检测在 ssnetstatlsof 三种环境下都能正确判定
  • SSL 任一路径失败时,最终摘要不再显示成功状态
  • SQLite / MariaDB 两种新装流程都能得到一致且可登录的实际配置
  • 自定义 XUI_MAIN_FOLDER 后,服务文件仍能正确启动
  • Arch、Debian/RHEL、Alpine 三类服务安装路径与执行路径一致
  • 在公网 IP 获取失败、80 端口不可用、证书签发失败等场景下,脚本能给出准确结果而非伪成功