仓库说到底就是一个索引文件
一句话总结
apt 仓库的本质是一个存放 .deb 文件的目录,加上一份名为 Packages 的索引文件。只要有这两项,file:/// 同样可以成为完整的软件仓库。
为什么需要这些知识
隔离网络、air gap、企业标准镜像、CI cache——无法访问互联网或不应访问互联网的环境,比想象中常见。此时有两个选择:手工逐个搬运所需的 .deb,或在内部建立完整仓库。第一种方式重复三次左右就会难以忍受,第二种方式只需建立一次,之后可以持续使用。
它是如何运作的
apt 实际从仓库读取的内容出乎意料地简单。
저장소 루트/
Packages <- 각 .deb 의 control 필드 + Filename + Size + SHA256
Packages.gz <- 위의 압축본 (apt 는 압축본을 선호한다)
Release <- 저장소 메타데이터 (Origin, Suite, Components, 체크섬)
*.deb <- 실제 패키지 파일
Packages 是一个文本文件,它把各软件包的 control 字段连接起来,再添加 Filename(相对于仓库根目录的路径)、Size 和 SHA256。生成它的工具包括适合简单场景的 dpkg-scanpackages,以及适合大规模仓库的 apt-ftparchive。
cd /root/repo
dpkg-scanpackages . /dev/null > Packages
gzip -kf Packages
随后,在 sources.list 中添加一行。
deb [trusted=yes] file:/root/repo ./
末尾的 ./ 表示 flat 仓库,即没有 dists 层级、Packages 直接位于根目录。[trusted=yes] 表示信任没有 GPG 签名的仓库。在实操或企业内部临时仓库中经常这样使用,但生产仓库必须签名。面对无签名仓库,即使有人在传输途中替换 .deb,也无法察觉。
这里必须区分两层验证。
| 层次 | 保证什么 | 工具 |
|---|---|---|
| checksum(SHA256) | 传输过程中没有损坏 | sha256sum -c |
| 签名(GPG) | 来源确实是已知的一方 | gpg --verify、apt-key/signed-by |
如果 checksum 只保存在同一介质上,整个介质被替换时,checksum 也会一起变化。因此,完整性的最后防线始终是签名。
在实际工作中会是什么样
“已经把软件包放进仓库,服务器为什么仍看不到?” 这是隔离网络运维最常收到的报障。原因通常只有两个:没有重新生成索引,遗漏了 dpkg-scanpackages 或 createrepo_c --update;或者客户端没有刷新 cache,未执行 apt-get update。两种情况都会制造“文件明明就在那里”的无奈局面。
在仓库名称中写入快照日期。 采用 name=LabHub local (snapshot 2026-08-15) 之类名称,六个月后面对“这台服务器安装的是哪个时点的内容?”这一问题,就能通过一行 apt-cache policy 回答。
把隔离网络导入变成流程
前一模块提到 USB 往返三四次的情况。要消除这种问题,必须把导入从临时跑腿变成可复现流程。要点是在外部通过机器计算,提前确定“需要带入什么”。
取得完整依赖图的求解结果。 在外部使用相同发行版、相同版本的环境实际安装所需软件包,并收集过程中下载的全部文件。真正执行安装很重要。仅计算清单时,内部环境已经拥有和尚未拥有的组件不同,很容易产生偏差。因此,核心措施是在外部准备一个状态与内部相同的容器。
在 bundle 中附带 manifest。 内容包括文件清单、每个文件的 checksum、获取文件时使用的发行版与仓库时点,以及原本准备安装什么。没有这份文档,几个月后不会有人知道这块 USB 中到底是什么。
在内部验证后安装。 使用 manifest 中的 checksum 确认传输未损坏;条件允许时,还应验证签名,然后更新仓库。如前所述,checksum 只保证未损坏,签名才保证来源。
记录安装结果。 必须保留何时把哪个 bundle 安装到哪台服务器的记录,日后发生问题时才能回答“这台服务器采用哪个时点的内容”。前面提到把快照日期写入仓库名称,就是成本最低的记录方式。
这套流程的价值不仅在于节省时间。隔离网络中最危险的行为,是以情况紧急为由跳过验证。流程一旦写成文档,即使在紧急情况下,也能明确知道自己准备跳过哪一步。
下一次实操要做什么
你将连续完成两个实操。首先,使用亲手构建的 .deb 建立 flat 仓库并完成安装;随后,完整下载已安装软件包的全部依赖,制作一份包含 manifest 和 checksum 的导入 bundle,重现离线安装。