三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

大陆机房 VPS 用 reinstall 一键脚本重装 NixOS 26.05 踩坑复盘:CentOS 7.2 老系统 + NAT 内网环境全记录

大陆机房 VPS 用 reinstall 一键脚本重装 NixOS 26.05 踩坑复盘:CentOS 7.2 老系统 + NAT 内网环境全记录

1. 背景与目标

本文记录一次在大陆机房 VPS 服务商「多开云」上,使用 bin456789/reinstall 一键脚本,将 CentOS 7.2.1511 64 位系统重装为 NixOS 26.05 的完整踩坑过程。整个过程前后折腾数小时,失败点集中在三处:reinstall 准备阶段 yum 装包全部失败、进入 Alpine 安装环境后 nixos-install 反复报 Cannot build、安装环境终端交互异常。

先交代环境参数,方便读者对照自身情况:

  • 服务商:多开云(大陆机房)
  • 原系统:CentOS 7.2.1511 64 位,无图形界面纯净模板,50G 系统盘
  • 硬件配置:2 核 / 2GB 内存 / 1G swap
  • 磁盘布局:系统盘 55.9G(/dev/sda,单分区挂 /)+ 数据盘 28G(/dev/sdb,挂 /data)
  • 网络环境:NAT 内网,机器内网 IP 为 10.178.x.x 段,公网靠服务商映射的高端口访问内网 22
  • 内核版本:3.10.0-327.el7(2015 年发布的 CentOS 7.2 内核)
  • 目标系统:NixOS 26.05(2026 年 5 月发布)

操作路径如下:上传 reinstall.sh 后执行bash reinstall.sh nixos 26.05 --username root --password <自定义密码>,脚本配置 grub,重启进 Alpine 3.24 安装环境,执行 nixos-install,预期装完自动重启进 NixOS。实际结果与预期相去甚远。

2. 失败点一:reinstall 准备阶段 yum 装包全部失败

reinstall 脚本在准备阶段需要调用 yum 安装 fdisk 等工具。在 CentOS 7.2 上,这一步直接全军覆没,脚本最终报***** ERROR *****退出。

根因在于:CentOS 7.2/7.3 这种老版本的 rpm 路径(/centos/7.3.1611/...)已被各镜像站从 os 目录移除,归档到 centos-vault。直接请求返回 404;部分老镜像站(yun-idc、btte)直接超时。yum 在所有镜像上失败,准备工具装不上,脚本自然无法继续。

这里要纠正一个常见认知:「CentOS 7 的 yum 源还能正常用」是错的。7.2/7.3 这种老版本早已不在各镜像站的常规 os 目录里,必须手动指向 centos-vault 才能继续。

实测 util-linux/libblkid 等 rpm 在 tuna/aliyun/sjtu 全部 404(7.3.1611 路径已迁 vault),yun-idc/btte 直接超时。修复分两步:

  • repo 指向 vault:把 repo 改为mirrors.tuna.tsinghua.edu.cn/centos-vault/7.3.1611/
  • 关闭 TLS 校验:vault 源 https 报curl#60 Peer's Certificate issuer is not recognized——2015 年 CentOS 7.2 的 CA 证书库太旧。修复是在 repo 各节加sslverify=0

修复后yum repolist从 0 包变成 11960 包,准备阶段才得以继续。

3. 失败点二:Alpine 安装环境中 nixos-install 反复报 Cannot build

好不容易进入 Alpine 3.24 安装环境后,nixos-install 又反复报Cannot build。这个问题同样有大陆机房特有的背景。

根因在于:Nix 二进制缓存 cache.nixos.org 在大陆不可达。Nix 回退从源码构建,而构建过程又要拉 GitHub 源码,大陆同样不通,最终只能报 Cannot build。

这里要纠正第二个常见认知:「reinstall 装 NixOS 一条命令就行」只对国外机器成立。大陆机房有两道坎:一是 CentOS 老系统 yum 源失效,装不上准备工具;二是 Nix 二进制缓存不可达,构建拉源码也不通,双重叠加导致安装反复失败。

结合本次执行的源码版本(bin456789/reinstall main 分支 commit73fa468c42b4482ec3faa2f7a6483f4f83c39a72,2026-08-06 提交,脚本头部兼容性标识SCRIPT_VERSION=4BACD833-A585-23BA-6CBB-9AA4E08E0004),可以进一步定位到具体代码:

  • channel 走 NJU,store 仍走官方:reinstall.sh 的setos_nixos函数(约 1570 行)里,大陆自动选南京大学镜像作为 channel(安装清单):mirror=https://mirror.nju.edu.cn/nix-channels。但 store(二进制缓存)仍默认官方 cache.nixos.org,大陆机房不可达,这是 nixos-install 反复报 Cannot build 的根因之一。
  • 构建失败链:从 /reinstall.log 实测,失败链为CVE-2025-15661.patch.drv(curl 安全补丁,从 GitHub 拉)→libssh2-1.11.1curl-8.21.0-sourcenixos-manual-htmlsystem-pathnixos-system,全链报Cannot build ... 1 dependency failed。cache.nixos.org 用wget -T 8测试直接超时,Nix 回退从源码构建,构建又要拉 GitHub 源码/补丁,大陆同样不通。

修复方向是给 nix.conf 的 substituters 配 USTC/TUNA/阿里/NJU 四镜像,并保留官方公钥cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=。注意公钥必须逐字符抄对——数字 0 敲成 O、h 敲成 H 都会导致下载的 nar 签名验证失败,全部回退构建,等于白配。

4. 失败点三:安装环境终端交互异常

第三个坑在终端交互层面。Alpine 安装环境默认不启动 sshd,公网端口连不上,只能靠服务商 VNC 控制台人肉操作。而 VNC 会话终端有两个怪问题:

  • 键盘首字符丢失:输密码 bnuj.3345 会变成 nu.j.3345,首字符被吞掉。
  • 剪贴板不同步:Cmd+V 只回显字符 v,粘贴内容无法进入终端。

这两个问题对自动化 agent 极不友好,基本只能靠人肉逐字符输入。这里要纠正第三个常见认知:「VPS 装系统全程可以自动化,agent 直接 SSH 操作即可」是错的。至少在 Alpine 安装环境阶段,没有 sshd,VNC 终端又有输入怪癖,自动化路径走不通。

5. 关键认知纠错:trans.sh 的用法

在排查过程中,还踩了一个关于 trans.sh 用法的坑。安装环境里的 /trans.sh不接受位置参数,直接执行sh /trans.sh nixos 26.05 ...会报unknown option nixos

trans.sh 靠 grub 内核参数(/proc/cmdline)驱动:reinstall.sh 把finalos_distro=nixosfinalos_mirror=...等写入内核引导参数,trans.sh 启动时自动读取。重跑只需sh /trans.sh(不带任何参数)。

这里要纠正第四个常见认知:「trans.sh 的用法和 reinstall.sh 一样,带参数跑」是错的。两者驱动方式完全不同,照搬 reinstall.sh 的带参用法必然报错。

本次实测的 /proc/cmdline 内容为finalos_distro=nixos finalos_mirror=https://mirror.nju.edu.cn/nix-channels finalos_releasever=26.05 extra_username=root,由 reinstall.sh 写 grub 时注入。手动带参执行sh /trans.sh nixos 26.05 ...会走参数解析器,直接报unknown option nixos

另外注意:Alpine 安装环境默认没有 bash。reinstall 本应apk add bash,但 apk 源失效时 bash 没装上,bash /trans.sh会报bash: not found,此时改用sh /trans.sh即可。

6. 关键认知纠错:手动改 nix.conf 配国内镜像无效

另一个容易白费功夫的点是手动修改 /etc/nix/nix.conf。trans.sh 内部有configure_nix_substituters()函数,每次启动都把 nix.conf 重写为单镜像substituters = $mirror/store(大陆自动选南京大学镜像 NJU)。用户手动改的多镜像配置在重跑时被覆盖,等于白改。

这里要纠正第五个常见认知:「手动改 /etc/nix/nix.conf 配好国内镜像就行」是错的。trans.sh 每次启动都会重写该文件,手动配置无法持久生效。

结合源码看,trans.sh 的configure_nix_substituters()函数(约 1825-1936 行)会执行:

nix_conf=/etc/nix/nix.conf echo "substituters = $mirror/store" >> "$nix_conf"

$mirror 来自内核参数 finalos_mirror(大陆=NJU)。所以正确做法不是手动改 nix.conf,而是用 sed 改 trans.sh 这一行,追加 USTC/TUNA/阿里三镜像,改完用 grep 确认第 1839 行生效,再重跑sh /trans.sh

7. 复盘总结

这次重装折腾数小时,核心教训可以归纳为三点:

  • 老系统 yum 源失效是第一个拦路虎:CentOS 7.2 的 rpm 路径已被归档到 centos-vault,准备阶段装工具就失败,后续无从谈起。
  • 大陆机房网络是第二个拦路虎:Nix 二进制缓存和 GitHub 源码都不可达,nixos-install 只能报 Cannot build。
  • 安装环境交互是第三个拦路虎:无 sshd、VNC 键盘首字符丢失、剪贴板不同步,自动化 agent 基本无法操作。

如果读者也遇到类似场景,建议在动手前先确认三件事:老系统 yum 源是否还能用、目标系统的二进制缓存在大陆是否可达、安装环境是否支持自动化交互。这三关都过了,再考虑用 reinstall 脚本走一键重装,否则大概率会陷入和我一样的反复失败循环。

8. 落地结论:问题清单与可复用修复链

把这次踩坑沉淀成可直接复用的结论。先看「多开云 centos7.2.1511 64位 50G 无图形界面纯净系统模板」这个模板本身的问题清单:

  • 系统过老(2015 年内核 3.10.0-327):CA 证书库无法验证现代 HTTPS 证书,curl/wget 全报 curl#60;yum 装任何新包都失败。
  • yum 源指向 7.3.1611(比系统版本还新的号):该路径已从 tuna/aliyun/sjtu 的 os 目录移除(归档 centos-vault),全部 404。
  • 纯净最小化模板缺工具:reinstall 准备阶段要现装 fdisk 等,yum 源坏则整流程卡死。
  • NAT 内网架构:无公网直连,公网服务靠服务商高端口映射内网 22;安装环境 sshd 默认不监听,运维只能走服务商 VNC 控制台——自动化 agent 无法直接接管。

对应的可复用修复链(大陆机房 + 老 CentOS 装 NixOS 26.05)如下:

  1. 修 yum:repo 指向 centos-vault/7.3.1611 +sslverify=0yum repolist恢复(实测 11960 包)。
  2. 运行bash reinstall.sh nixos 26.05 --username root --password <自定>,重启进 Alpine 3.24 安装环境。
  3. Alpine 里先修 apk 源(阿里云 v3.24)+apk add bash(Alpine 默认无 bash)。
  4. 改 /trans.sh:sed 把configure_nix_substituters的 substituters 行追加 USTC/TUNA/阿里(NJU 对新 commit 的 nar 同步滞后,会缺包触发构建)。
  5. sh /trans.sh无参重跑(参数来自 /proc/cmdline,勿手传),Nix 走国内镜像下载,nixos-install 成功。
  6. 装好的 NixOS 默认开防火墙,外部 SSH 需在 configuration.nix 放行 22 后 nixos-rebuild。

对 agent 的总体建议:reinstall 流程本身自动化程度高(grub 注入参数、安装全自动),但大陆机房 + 老模板有三层网络坎(yum 源 / HTTPS 证书 / Nix 缓存),必须预判;VNC 控制台人肉操作不可依赖(键盘丢首字符、剪贴板不同步),能改脚本就 sed 改脚本(非交互化),能轮询日志就别长连交互。

9. 三类读者速查

9.1 人类开发者自查命令

按顺序自查,能快速定位问题出在哪一层:

  • yum repolist:应为非 0 包,否则 yum 源没修好。
  • cat /etc/nix/nix.conf:substituters 应为多镜像而非单 NJU。
  • grep substituters /trans.sh:确认 sed 生效。
  • 安装环境里tail -fn+1 /reinstall.log:观察 downloading 来源。

9.2 对话式 AI 一句话问法

大陆机房 CentOS 7.2 模板用 reinstall 装 NixOS 反复 Cannot build 怎么修?回答要点:

  1. 老系统 yum 源换 vault + sslverify=0。
  2. Alpine 环境修 apk 源、装 bash。
  3. sed 改 /trans.sh 的 substituters 为多国内镜像(防覆盖)。
  4. sh /trans.sh无参重跑。
  5. 装后防火墙放行 22。

9.3 代码 Agent 可复制命令(脱敏,按序)

第一步,老 CentOS 修 yum(vault + 跳过 TLS 校验):

cat > /etc/yum.repos.d/CentOS-Base.repo <<'EOF' [base] baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.3.1611/os/x86_64/ gpgcheck=0 sslverify=0 EOF yum repolist

第二步,Alpine 安装环境:sed 改 trans.sh substituters(防重跑覆盖):

sed -i 's|substituters = $mirror/store|substituters = $mirror/store https://mirrors.ustc.edu.cn/nix-channels/store https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store https://mirrors.aliyun.com/nix-channels/store|g' /trans.sh

第三步,重跑(无参,参数来自 /proc/cmdline):

sh /trans.sh

注意:agent 环境做 SSH 密码认证需先unset SSH_ASKPASS SSH_ASKPASS_REQUIRE DISPLAY;expect 的 Tcl 双引号里[y/N]会触发命令替换,模式请用大括号{...}

← 返回列表