openSUSE:Build Service Signer
描述
openSUSE Build Service 支持使用 GPG 密钥对 RPM 和 DEB 包进行签名。 这相对自动化;但是,设置签名者可能既漫长又复杂,并且可能会暴露一些不必要的信息。 您需要确保在锁定的服务器上设置此功能。
说明
所需软件包
您将需要
- 来自 openSUSE:Tools 仓库的 obs-signd 包
- 应用了 files-are-digests.patch 的 gpg2 包
obs-signd 包(从大约版本 2.1.12 开始)对虚拟需求 gpg2_signd_support 有依赖性,而后者又由适当的 gpg2 包互补提供。
openSUSE(从 11.3 及更高版本开始)使用带有 gpg2_signd_support 的 gpg2。 对于其他发行版,需要 GPG 的补丁。
请注意,Gnupg 2.2 具有新的上游功能,这将使此补丁过时,但 obs-signer 需要更新才能利用它。
设置 GPG 密钥
您需要 su 到 root 并使用 gpg 创建一个主密钥,其中包含多种加密和签名类型,如下所示
$ gpg --gen-key
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 5y
Key expires at Tue Aug 4 12:15:28 2015 CEST
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: My Build Service
Email address: obsrun@localhost
Comment:
You selected this USER-ID:
"My Build Service <obsrun@localhost>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.
(Passphrase dialog.)
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2015-08-04
pub 2048R/F86E2EDC 2010-08-05 [expires: 2015-08-04]
Key fingerprint = E020 2A9C 1D89 662C A354 FB37 87DD A101 F86E 2EDC
uid My Build Service <obsrun@localhost>
sub 2048R/D849EAAB 2010-08-05 [expires: 2015-08-04]
由于有可能使用 DSA 对软件包进行签名,因此您还应该添加一个 DSA 子密钥
$ gpg --edit F86E2EDC
gpg (GnuPG) 2.0.12; Copyright (C) 2009 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
pub 2048R/F86E2EDC created: 2010-08-05 expires: 2015-08-04 usage: SC
trust: ultimate validity: ultimate
sub 2048R/D849EAAB created: 2010-08-05 expires: 2015-08-04 usage: E
[ultimate] (1). My Build Service <obsrun@localhost>
Command> addkey
(Passphrase dialog.)
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
Your selection? 3
DSA keys may be between 1024 and 3072 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 2015-08-04
不要选择“5y”助记符,而是选择主密钥的实际日期,以便子密钥在大致相同的时间过期。
有些程序[哪个?] 无法处理 DSA 2048,因此如果您受到影响,您可能希望将自己限制为 1024 位 DSA 密钥。
Key expires at Mon Aug 24 11:59:24 2015 CEST
Is this correct? (y/N) y
Really create? (y/N) y
pub 2048R/F86E2EDC created: 2010-08-05 expires: 2015-08-04 usage: SC
trust: ultimate validity: ultimate
sub 2048R/D849EAAB created: 2010-08-05 expires: 2015-08-04 usage: E
sub 2048D/D5C8DB1B created: 2010-08-05 expires: 2015-08-24 usage: S
[ultimate] (1). My Build Service <obsrun@localhost>
重复 addkey 步骤,这次选择 Elgamal。 (确保您有 Elgamal 2048 位[为什么?]。)最终,您将在单个密钥中拥有所有可能的方案
pub 2048R/F86E2EDC created: 2010-08-05 expires: 2015-08-04 usage: SC
trust: ultimate validity: ultimate
sub 2048R/D849EAAB created: 2010-08-05 expires: 2015-08-04 usage: E
sub 2048D/D5C8DB1B created: 2010-08-05 expires: 2015-08-24 usage: S
sub 2048g/D4A6E8F1 created: 2010-08-05 expires: 2015-08-24 usage: E
[ultimate] (1). My Build Service <obsrun@localhost>
准备签名者
您需要创建一个目录,/root/.phrases。
在该目录中创建一个文件,以 GPG 密钥的电子邮件命名,即,在我们的示例中为 obsrun@localhost。 该文件的内容应该是您的密钥密码,没有尾随换行符。
现在,运行以下命令
出于某种原因,sign 会在 root 和 / 中查找密钥。 它们必须同时存在于这两个位置。
配置签名者
首先导出密钥,以便 OBS 可以使用它...
gpg --armor --export F86E2EDC > /etc/ourkeyfile.asc
编辑 /usr/lib/obs/server/BSConfig.pm。
更改为以下内容
our $gpg_standard_key = "<location of the keyfile>"; # The above should be something like "/etc/keyfile.asc". our $sign = '/usr/bin/sign'; # Extend sign call with project name as argument "--project $NAME" our $sign_project = 0; # Global sign key our $keyfile = '<location of the keyfile>'; # Create a key by default for new projects, if top level have not one our $forceprojectkeys = 1;
keyfile 应该是您创建的密钥,导出为 .asc 格式。 通过取消注释 $sign,Build Server 知道要使用签名者。
现在,编辑 /etc/sign.conf 以显示以下内容
user: obsrun@localhost allowuser: obsrun allow: 127.0.0.1 phrases: /root/.phrases
这允许 sign 使用密钥。
如果您运行的版本低于 obs-signd-2.1.2,其中/etc/permissions.d/sign丢失,请创建此文件并添加到其中
/usr/bin/sign root:obsrun 4750
创建此文件后,运行 SuSEconfig --module permissions。
激活签名者
运行
insserv obssignd obssigner rcobssignd start rcobssigner start
尽情享受吧!
为 EFI 安全启动签名 EFI 二进制文件/内核模块
OBS 可以签名和重新打包包含用于安全启动的 EFI 二进制文件或内核模块的 RPM 或 Debian 包。
请查看 pesign-obs-integration 源代码 或 软件包 以获取详细信息。
分离的签名者机器
任何具有 root 权限的 OBS 管理员都可以访问主 GPG 私钥,从而解密和访问每个项目私钥。 如果这不可取,可以将一台单独的机器添加到同一 LAN,并可以进一步限制并用作远程签名者。 建议遵循所有针对关键任务机器的最佳实践(裸机、加密磁盘、仅通过公钥访问 ssh、严格的防火墙规则、与主 OBS 实例的背靠背网络连接等)。
要安装的唯一软件是 obs-signd 包。 按照上述说明生成 GPG 主密钥,但在 /etc/sign.conf 中,不要使用 127.0.0.1,而是在“allow”字段中设置主 OBS 实例的 IP 地址。 同时,在主 OBS 实例的同一文件中,在“server”字段中使用签名者机器而不是 127.0.0.1。 签名者/signd 使用的默认 TCP 端口是 5167。
故障排除
--project
$sign_project 会导致签名者使用额外的 --project $projectname 参数被调用。 这适用于除了 obs-sign 之外的其他签名实现,后者可能会执行自己的密钥管理。<ref>http://lists.opensuse.org/opensuse-buildservice/2010-08/msg00035.html</ref>
没有全局密钥
将 $keyfile 保留在 BSConfig.pm 中为空/注释状态会导致在没有可用 signkey 的项目中,软件包将一直停留在“签名”状态,直到可以执行签名为止。
未找到密钥和 GNUPGHOME
obs-signd-2.1.2-1.1 rpm 包中的 /etc/init.d/obssignd 在启动 signd 守护程序之前将 GNUPGHOME 设置为 /obs/gnupg。 如果您遵循上述说明,您的 GNUPGHOME 将为 /root/.gnupg。
一种解决方案是将 /root/.gnupg 复制到 /obs/gnupg,或使用符号链接。 另一种方法是编辑 /etc/sysconfig/signd 以设置 GNUPGHOME(查看 /var/adm/fillup-templates/sysconfig.signd)。
在构建/签名时没有 OpenSSL 证书
只有在有可用项目密钥(或其父密钥)时,OBS 才会创建并提供用于 EFI 签名的 OpenSSL 证书。 如果直接使用全局主密钥,则不可能这样做。 使用 osc signkey --create $project 创建项目密钥。
项目密钥创建和存储细节
本段试图记录 signd 在签名项目时的工作原理。
在新的项目的首次签名请求时,如果项目或其任何父项目都没有密钥,后端将要求 signd 创建新的密钥对和 SSL 证书。 它们存储在 DB 中。
密钥对也存储在文件系统上,位于 $projectsdir/$projectid.pkg 作为 _pubkey,一种 GPG ASCII 格式的公钥,以及 _signkey,一种 GPG 二进制格式的私钥,使用签名者的 GPG 公钥(即通过本页上的说明创建的密钥)加密并存储为 ASCII 十六进制字符串。
在每次签名请求时,后端会将要签名文件/数据以及项目的公钥和加密的私钥发送到 signd。 因此,只有签名者机器和那些可以访问它的人才能访问项目的私钥。