开发者Wiki:Repo DB 签名
外观
[RFC] Repo DB 签名 (以及 ISO/其他构件)
我们的仓库 DB 当前未签名,因为将 GPG 私钥放在向仓库添加包的服务器上存在安全隐患。然而,我们希望自动签名我们的 db、iso 和其他构件,因此必须做出一些妥协。
关于这个话题已经进行了几次讨论
签名仓库数据库就像下面一样简单
repo-add -v -s foo.db pacman-3.0.0-1-x86_64.pkg.tar.gz lrwxrwxrwx 1 jelle users 13 Aug 15 20:56 foo.db -> foo.db.tar.gz lrwxrwxrwx 1 jelle users 17 Aug 15 20:56 foo.db.sig -> foo.db.tar.gz.sig -rw-r--r-- 1 jelle users 504 Aug 15 20:56 foo.db.tar.gz -rw-r--r-- 1 jelle users 503 Aug 15 20:56 foo.db.tar.gz.old -rw-r--r-- 1 jelle users 310 Aug 15 20:56 foo.db.tar.gz.sig lrwxrwxrwx 1 jelle users 16 Aug 15 20:56 foo.files -> foo.files.tar.gz lrwxrwxrwx 1 jelle users 20 Aug 15 20:56 foo.files.sig -> foo.files.tar.gz.sig -rw-r--r-- 1 jelle users 782 Aug 15 20:56 foo.files.tar.gz -rw-r--r-- 1 jelle users 782 Aug 15 20:56 foo.files.tar.gz.old -rw-r--r-- 1 jelle users 310 Aug 15 20:56 foo.files.tar.gz.sig
repo-add 签名仓库如下
gpg --detach-sign --use-agent --no-armor
无论是有意还是无意,repo-add 都可以仅签名 db 而不添加包。
repo-add foo.db.tar.gz -s
提出的解决方案
从“安全”隔离区签名 (解决方案 1)
创建一个专用的签名主机,该主机接收文件,然后返回签名。
应在此主机上添加一些限制
- 签名速率限制 (每月仅签名一次 ISO)
- 安全地记录签名过的构件
- 来自特定 IP 的请求 (这应该是仅 repos.archlinux.org)
- 身份验证 (SSH?)
- 独立主机、虚拟机或容器?
- 最小访问列表
参见 Bluewind 的提案。
实现: https://git.server-speed.net/users/flo/alass/[失效链接 2025-03-15—未解析域名]
从“安全”隔离区签名 (解决方案 2)
与将任意文件发送到“安全”隔离区不同,隔离区会拉取要签名文件并返回一个新签名文件。
工作流程
- 触发 DB 更改操作,仓库被锁定。
- 创建一个新的 DB 文件并放入临时位置。
- 发送通知给(或更准确地说,由)安全隔离区,告知有新的 DB 文件需要签名。
- 安全隔离区检索要签名文件。
- 它对其进行签名,并(可选,待定)记录其已完成。
- 将签名上传回 DB 服务器。
- DB 服务器将 DB 及其签名放到位,释放仓库锁并重置通知通道。
全局实现细节
- 无特别/新内容。
- 在此需要将新生成的 DB 放在特定位置。
- 此时,DB 更改操作有两种主要方式可以通知需要新的签名
- 不执行任何操作: 隔离区正在查找临时位置的 DB,并在看到文件时知道有事要做(而不是例如 404)。
- 写入特定文件: 文件可以包含一个 0 (表示没有新的 DB 需要签名),或一个 1,甚至实际 DB 文件的校验和,以避免传输过程中的损坏问题。
- 如果执行了上述第二种情况,只需使用同一种安全连接检索 DB。
- 这里有很多值得思考的地方。特别是*安全*日志记录很困难。这将在下面详细介绍。
- 这里有很多可能的上传机制,请参见下文。
- 这要求 DB 更改操作正在等待签名返回。
具体细节
- 关于从 DB 服务器检索文件到隔离区: 我能想到的最安全的方法是使用一个非常加固的 HTTPS 连接。这意味着服务器和客户端都使用自定义 CA(可能位于隔离区)颁发的证书进行身份验证,仅支持 TLS 1.3,ECDHE 与 Ed448 和 Poly1305-Chacha20 或 AES-GCM。我们需要在监视通知文件时保持连接打开,以避免在监视频率上重新建立新的 TLS 会话。
- 上传签名回来: 我们可以使用相同的设置通过 HTTP(S) 上传,但不确定这是否非常重要(除非我们签了一个错误的文件,签名本身是公开文件,所以…)。需要仔细考虑攻击场景。
- 对于以上两点,我们可以强制使用双方的 IP 地址以提高安全性。仓库服务器上的实际入口点也可以是 TOR 隐藏服务,但不确定我们是否想要这样做(我猜可能有缺点)。
- 现在,让我们深入研究日志记录和威胁模型。这可能是困难的部分。
- 如果我们不考虑隔离区可能被攻破,那么我们只需要签名脚本还将签名记录到远程上传点和本地文件(以防网络故障)。
- 如果我们考虑隔离区可能被攻破但没有 root 权限,那么密钥只能由 root 访问或放在 HSM 中,但(仅限 root 可写)签名+日志脚本可供普通用户使用。这样攻击者就无法在不记录的情况下签名文件。
- 如果我们考虑隔离区被 root 攻破,拥有 HSM 是唯一能让我们免于完全失败的保护(它需要攻击者维持在隔离区的存在,这将防止长期攻击),但这基本上还是输定了。
请注意,其中大多数具体细节也适用于解决方案 1。
与解决方案 1 相比的优点
- 隔离区上的开放端口至少少了一个(“提交”端口),这意味着如果只允许物理访问该机器而不是 SSH,则可以将其降至零(我们也可以将 SSH 隐藏在 TOR 中)。
- 取决于实现细节,对任意文件签名的保护可能更健壮。
与解决方案 1 相比的缺点
- 双方都需要监视器(等待签名文件,等待签名上传)vs 几乎没有(嗯,你仍然需要等待签名返回,但这是你的“握手”的一部分)。
- 为了获得不多的安全性而增加了复杂性(嗯,在某些点上,安全性的提升需要大量的努力)。
https://www.mail-archive.com/arch-dev-public@archlinux.org/msg25637.html
比较 收益/陷阱
- 两个解决方案都有一个问题,那就是存在一段时间仓库 db 未签名。解决方案是使用临时 db,然后移动该 db。
其他发行版的解决方案
Debian
OpenSuSe 构建服务
OBS (OpenSuSe 构建服务) 有一个签名守护程序,它接受数据并返回签名。
Fedora
待解决问题
- 应该使用哪个密钥来签名仓库 db?
- 通过 SSH 进行远程签名的 Repo DB?
- 分发公钥。在密钥环中?
- 使用硬件令牌?