如何使用Gitian构建Linux内核?求file.yml编写指引
用Gitian构建Linux内核的实践指南
我正好有过用Gitian做Linux内核确定性构建的实践经验,完全能满足你多机验证哈希的安全需求。下面一步步给你拆解怎么写file.yml,以及处理依赖和构建的关键细节:
一、Gitian构建内核的核心逻辑
Gitian的核心是在隔离的虚拟机环境里,用固定版本的依赖和一致的构建步骤生成可复现的产物。对于内核来说,关键是要锁定所有依赖版本、使用确定性的编译参数,这样不同机器跑出来的哈希才会完全一致。
二、编写file.yml的关键模块
我给你一个实用的模板,你可以根据自己的内核版本调整:
1. 基础配置部分
这部分定义构建环境的基础参数,比如虚拟机的系统镜像、架构:
--- name: linux-kernel builder: name: debian version: "bookworm" arch: amd64 # 根据你的机器架构调整,比如arm64
2. 依赖安装部分
内核构建需要的依赖很多,这里要明确指定版本(或者用Debian稳定版的默认版本,确保一致性):
packages: - build-essential - libncurses-dev - bison - flex - libssl-dev - libelf-dev - bc - rsync - git # 如果需要其他依赖,比如clang,也可以加上 # - clang # - llvm
注意:如果你的内核版本需要特定版本的依赖(比如旧内核需要老版本的gcc),可以在
packages里指定版本号,比如build-essential=12.9,确保不同机器安装的依赖完全一致。
3. 构建脚本部分
这部分是核心,包含获取源码、配置内核、编译的步骤,要确保每一步都是确定性的:
scripts: - script: | # 克隆指定版本的内核源码(这里用5.15 LTS为例) git clone --depth 1 --branch v5.15 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git cd linux # 使用默认的defconfig(或者你自己的确定性配置) make defconfig # 开启确定性编译的关键参数 echo "CONFIG_BUILD_SALT=\"\"" >> .config echo "CONFIG_LOCALVERSION=\"\"" >> .config echo "CONFIG_DEBUG_INFO_NONE=y" >> .config # 关闭调试信息,减少哈希差异 echo "CONFIG_RETPOLINE=y" >> .config # 编译内核,指定线程数(可以根据VM资源调整) make -j$(nproc) bzImage modules # 安装内核到指定目录,方便后续收集产物 make INSTALL_MOD_PATH=../output modules_install cp arch/x86/boot/bzImage ../output/vmlinuz-5.15
这里的关键是不要用随机化的编译参数,比如
CONFIG_LOCALVERSION要设为空,CONFIG_BUILD_SALT也要清空,避免每次构建生成不同的标识。另外,调试信息会影响哈希,所以建议关闭。
4. 产物收集部分
指定要输出的文件,Gitian会把这些文件打包并生成哈希:
artifacts: - output/vmlinuz-5.15 - output/lib/modules/5.15/
三、多机验证的步骤
- 在两台不同的机器上,确保Gitian builder的基础VM完全一致(用同一个
bin/make-base-vm生成的镜像)。 - 分别在两台机器上运行:
bin/gbuild file.yml - 构建完成后,Gitian会在
result目录下生成linux-kernel-*-amd64-build.assert文件,里面包含所有产物的SHA256哈希。 - 对比两台机器上的
assert文件,只要哈希完全一致,就说明构建是确定性的。
四、我踩过的坑和注意事项
- 内核配置的确定性:如果你用自己的
.config,要确保它没有包含任何随机生成的选项,最好是从defconfig修改后保存的,不要用make menuconfig生成的(可能会有隐藏的随机参数)。 - 依赖版本一致性:如果用Debian的测试版或不稳定版,依赖版本可能会变,建议用稳定版(比如bookworm),或者指定具体版本号。
- 时间戳问题:Gitian会自动设置虚拟机的时间为构建开始的时间,但有些编译工具可能还是会用到系统时间,你可以在脚本里手动设置时间,比如
date -s "2024-01-01 00:00:00"。 - 架构一致性:两台机器的架构要一致(比如都是amd64),不然构建出来的产物肯定不一样。
内容的提问来源于stack exchange,提问作者Poperton
相关产品推荐
相关产品推荐

