6 共享状态签名
OpenEmbedded Build System 内置了通过复用预构建产物来节省执行时间的 机制,即 共享状态缓存(sstate 缓存)。这些产物存放在目录( SSTATE_DIR )中,默认不签名。
本文介绍启用共享状态签名的步骤。此功能完全依赖
GPG,因此示例均使用 gpg 命令行工具。
6 主机要求
由于 GPG 不属于默认的 主机要求,需要自行在主机上安装。
例如,基于 Debian 的发行版通过 gpg 软件包提供该工具。安装方法如下:
$ sudo apt-get install gpg
显示 GPG 版本,确认安装成功:
$ gpg --version
6 使用 GPG 生成公私钥对
备注
如果已有公私钥对,可以跳过此步骤。
两个相互独立的任务需要用到公私钥对:
使用 私钥 为 OpenEmbedded Build System 生成的共享状态产物签名。
复用共享状态产物时,使用 公钥 验证它们。
备注
关于公钥密码学的更多信息,见 https://en.wikipedia.org/wiki/Public-key_cryptography。
使用 gpg 命令行工具生成新的公私钥对:
$ gpg --full-generate-key
该工具会引导你完成创建密钥对的各个步骤。
完成后,应能使用以下命令列出新密钥:
$ gpg --list-keys
pub ed25519 2026-04-17 [SC]
4049A47E3AAA99D0250966DC5B97632FA7F4E942
uid [ultimate] Antonin Godard (SState Signing) <antonin.godard\@bootlin.com>
sub cv25519 2026-04-17 [E]
记下上例中的密钥标识符
4049A47E3AAA99D0250966DC5B97632FA7F4E942,配置构建时会用到它。
6 配置构建系统为共享状态产物签名
6 共享状态的位置
需要配置构建系统,使其在生成新的共享状态产物时进行签名。任务执行完成后, 便会生成新的产物。
以下各节假定构建系统的共享状态目录( SSTATE_DIR )定义如下:
SSTATE_DIR = "${TOPDIR}/sstate-cache"
假设此目录和临时目录( TMPDIR )都为空,运行
gettext-minimal-native 配方的 create_recipe_spdx 任务:
$ bitbake gettext-minimal-native -c create_recipe_spdx
本文将始终以此命令为例。
执行后,共享状态目录中应出现新文件:
$ find $BUILDDIR/sstate-cache/ -name "*gettext-minimal-native*create_recipe_spdx*"
sstate-cache/universal/a3/6e/sstate:gettext-minimal-native:x86_64-linux:1.0:r0:x86_64:14:a36ef66df6b8c0cb5a849bc70a99dcfd61e4bacd11cefe6bbaf4978b2b3b617a_create_recipe_spdx.tar.zst
sstate-cache/universal/a3/6e/sstate:gettext-minimal-native:x86_64-linux:1.0:r0:x86_64:14:a36ef66df6b8c0cb5a849bc70a99dcfd61e4bacd11cefe6bbaf4978b2b3b617a_create_recipe_spdx.tar.zst.siginfo
这些是 OpenEmbedded Build System 默认生成的共享状态产物。它们 默认不使用 GPG 签名,下面介绍如何为这些产物添加签名。
备注
尽管名称如此,siginfo 文件与 GPG 签名无关。
6 启用共享状态签名
在主机的 安全位置 创建新的 configuration file,并添加以下语句:
SSTATE_VERIFY_SIG = "1"
SSTATE_SIG_KEY = "4049A47E3AAA99D0250966DC5B97632FA7F4E942"
SSTATE_SIG_PASSPHRASE = "<your GPG key passphrase>"
建议将这些语句放入单独的文件,因为它们包含秘密信息,不应共享。
本例假定该文件为 conf/sstate-sig-key.conf。
可通过以下命令确保文件归你所有,且其他用户无法读取:
$ chown $USER:$USER conf/sstate-sig-key.conf
$ chmod o-rwx conf/sstate-sig-key.conf
文件中的语句定义了以下变量:
SSTATE_VERIFY_SIG:将此变量设为 "1" 可启用共享状态签名功能。
SSTATE_SIG_KEY:用私钥为共享状态产物签名的 GPG 密钥标识符。
在本例中,它对应 前文 中
gpg --list-keys命令输出的 标识符。SSTATE_SIG_PASSPHRASE:保护私钥的口令,在创建密钥对时指定。
测试配置:
继续使用
gettext-minimal-native示例。首先删除已有的共享状态产物, 确保重新生成do_create_recipe_spdx任务的共享状态产物:$ rm -r sstate-cache/
运行
gettext-minimal-native的create_recipe_spdx任务,但这次 将新的sstate-sig-key.conf文件传给 BitBake:$ bitbake -R conf/sstate-sig-key.conf gettext-minimal-native -c create_recipe_spdx
再次列出共享状态目录中的文件:
$ find sstate-cache/ -name "*gettext-minimal-native*create_recipe_spdx*"
sstate-cache/universal/a3/6e/sstate:gettext-minimal-native:x86_64-linux:1.0:r0:x86_64:14:a36ef66df6b8c0cb5a849bc70a99dcfd61e4bacd11cefe6bbaf4978b2b3b617a_create_recipe_spdx.tar.zst
sstate-cache/universal/a3/6e/sstate:gettext-minimal-native:x86_64-linux:1.0:r0:x86_64:14:a36ef66df6b8c0cb5a849bc70a99dcfd61e4bacd11cefe6bbaf4978b2b3b617a_create_recipe_spdx.tar.zst.sig
sstate-cache/universal/a3/6e/sstate:gettext-minimal-native:x86_64-linux:1.0:r0:x86_64:14:a36ef66df6b8c0cb5a849bc70a99dcfd61e4bacd11cefe6bbaf4978b2b3b617a_create_recipe_spdx.tar.zst.siginfo
新增了一个 .sig 文件。这说明产物已成功签名,签名保存在单独的
.sig 文件中。
6 验证已签名的共享状态产物
现在已经配置构建为共享状态产物签名,下面介绍如何使用与私钥对应的公钥 验证这些产物。
备注
共享状态的签名和验证可以在两台不同的主机上进行,一台主机负责签名, 另一台只验证产物。推荐这样做,因为不应在多台主机之间共享私钥。
在 configuration file (例如 站点配置文件 )中加入以下语句:
SSTATE_VERIFY_SIG = "1"
SSTATE_VALID_SIGS = "5B97632FA7F4E942"
这些语句定义了:
SSTATE_VERIFY_SIG:将此变量设为 "1" 可启用共享状态签名功能。
SSTATE_VALID_SIGS:以空格分隔的密钥标识符列表,指定可接受哪些 密钥签名的共享状态产物。
这意味着,只有使用对应密钥标识符的私钥签名的共享状态才会被复用。
注意,这里使用的是密钥标识符的短形式,即
gpg --list-keys显示的 长形式标识符的最后 16 个字符(下方以粗体显示):pub ed25519 2026-04-17 [SC] 4049A47E3AAA99D0250966DC5B97632FA7F4E942 uid [ultimate] Antonin Godard (SState Signing) <antonin.godard@bootlin.com> sub cv25519 2026-04-17 [E]
检查签名验证是否正常工作:
首先删除之前构建的临时输出( TMPDIR ),让 OpenEmbedded Build System 利用共享状态重新构建所有内容:
$ rm -rf tmp/
然后再次运行任务:
$ bitbake gettext-minimal-native -c create_recipe_spdx
要确认成功使用了共享状态产物,请在 BitBake 的最新日志文件中 查找
create_recipe_spdx对应的 setscene 任务:$ grep create_recipe_spdx_setscene tmp/log/cooker/<machine>/console-latest.log NOTE: Running setscene task 1 of 1 (../layers/openembedded-core/meta/recipes-core/gettext/gettext-minimal-native_1.0.bb:do_create_recipe_spdx_setscene) NOTE: recipe gettext-minimal-native-1.0-r0: task do_create_recipe_spdx_setscene: Started NOTE: recipe gettext-minimal-native-1.0-r0: task do_create_recipe_spdx_setscene: Succeeded
共享状态已成功验证并使用!
备注
要确认共享状态验证有效,可以在 SSTATE_VALID_SIGS 中设置一个 “虚假”的公钥标识符:
SSTATE_VALID_SIGS = "CAFECAFECAFECAFE"
再次删除临时输出:
$ rm -r tmp/
现在尝试执行任务:
$ bitbake gettext-minimal-native -c create_recipe_spdx
控制台应输出 BitBake 的警告:
WARNING: gettext-minimal-native-1.0-r0 do_create_recipe_spdx_setscene: No accepted signatures found. Good signatures found: 5B97632FA7F4E942.
WARNING: gettext-minimal-native-1.0-r0 do_create_recipe_spdx_setscene: Cannot verify signature on sstate package ../build/sstate-cache/universal/a3/6e/sstate:gettext-minimal-native:x86_64-linux:1.0:r0:x86_64:14:a36ef66df6b8c0cb5a849bc70a99dcfd61e4bacd11cefe6bbaf4978b2b3b617a_create_recipe_spdx.tar.zst, skipping acceleration...
WARNING: gettext-minimal-native-1.0-r0 do_create_recipe_spdx_setscene: No sstate archive obtainable, will run full task instead.
WARNING: Logfile for failed setscene task is ../build/tmp/work/x86_64-linux/gettext-minimal-native/1.0/temp/log.do_create_recipe_spdx_setscene.6994
WARNING: Setscene task (../layers/openembedded-core/meta/recipes-core/gettext/gettext-minimal-native_1.0.bb:do_create_recipe_spdx_setscene) failed with exit code '1' - real task will be run instead
可以看到,这不会阻止 BitBake 继续运行,但它会执行实际任务, 不再复用共享状态。