SDB:安全安装源

跳转到:导航搜索

安全安装源

您可以从许多以及各种互联网资源获取 SUSE Linux 的安装介质或在线安装源,这些资源提供额外的软件包作为安装源。这大大提高了 openSUSE 项目的可扩展性,并为 openSUSE 生态系统添加了许多有趣的软件包。

但是,使用这些源始终存在潜在风险。您如何知道安装源未被修改、完整且不包含任何恶意代码?

从 SUSE Linux 10.1 开始,这个问题已通过使用加密签名和校验和的组合来解决。

以下是 SUSE Linux 10.1 及更高版本中元数据和软件包签名概念的简要概述

我们使用分离的 GPG 签名来签署安装源/仓库中最重要的元数据文件。 针对的是两种安装源类型

“经典”SUSE 风格安装源

这是我们在安装介质上使用的。 它们通常被称为“YaST 源”,尽管 YaST 也支持其他源。 有两个入口点

文件 "media.1/products"

此文件列出了安装源文件树根目录的绝对路径,指向介质上的产品。 这对于多产品介质很有趣。 但通常只有一行,例如:

   / SUSE-Linux-Enterprise-Desktop 10

此文件将使用 SUSE 密钥对所有来自 SUSE 的产品进行签名。 用于验证签名的公钥(GPG 公钥,ASCII 盔甲保护)位于 "products.key" 文件中,以方便使用。

此密钥还将从 initrd(始终首先启动的初始可引导 Linux 镜像,如果您运行安装介质)导入,因此 YaST 通常已经知道它。 目前的 beta 版本尚未实现这一点。 初始密钥是 YaST 始终信任而不询问的密钥。 该密钥通常也位于安装介质上,作为

   /gpg-pubkey-9c800aca-40d8063e.asc

(此密钥可能会更改。 以上是当前使用的密钥。)

"products" 的签名位于 "products.asc" 文件中。

当 YaST 检测到安装源时,它会检查是否存在 "products" 文件,然后检查它是否使用已知密钥签名。 如果根本没有签名或使用未知密钥,或者密钥位于介质上但未受信任(尚未),系统会询问用户该怎么办。

我们对 "products" 文件进行签名,以确保没有人可以向安装源添加不属于该源的产品。

文件 "content"

对于每个产品,都有一个 "content" 文件。 如果没有 "products" 文件告诉我们产品的位置,我们会在安装源的根目录中查找 "content" 文件。

“content” 文件以与“products” 文件相同的方式签名,因此有一个“content.key”(通常,但不一定与“products.key” 相同)。

与旧版本中的“content” 文件相比,我们添加了额外的数据。 有两个新的键:META 和 KEY。 以下是两个示例

   META SHA1 08579e4b28287d6aedd954098b64c6bb49d17367 packages
   KEY SHA1 a108c6aab19fe604fa98ef299cdce6e6ba275f09 gpg-pubkey-0dfb3188-41ed929b.asc

META 密钥已添加到键 DESCRDIR 中命名的目录中的所有文件,例如:

   DESCRDIR suse/setup/descr

在典型的 SUSE Linux 上。

在使用 DESCRDIR 中的任何文件之前,YaST 将在 "content" 中查找该条目。 当前,该条目是 SHA1 校验和后跟软件包名称。 这可能会更改为 SHA256 校验和。

KEY 条目列出了 YaST 应该从介质导入的所有密钥。 这些密钥可用于检查 RPM 签名和元数据签名,并将存储在 RPM 数据库中,因此可以使用 "rpm --checksig" 进行包级别验证。

YaST 默认信任这些 KEY,因为 KEY 列表位于由默认受 initrd 信任的初始密钥签名的文件中。

链中的下一步是在 DESCRDIR 中 "packages" 文件。

如果您熟悉其语法,您会看到我们也在那里添加了一个新的标签,紧随 "Pkg:" 标签之后。 这是默认内核条目的前两行的示例

   =Pkg: kernel-default 2.6.16 13 i586
   =Cks: SHA1 8c8eb2b605e1d626c22bea8dd0c3b05885432b16

我们再次有一个 SHA1 校验和。

因此,从初始密钥(如果您不信任安装介质,则需要自行验证)通过 "product" 和 "content" 文件到各个软件包,存在一致的信任链。 该链确保所有这些文件都属于那里并且未被篡改。

在软件包级别,我们可能会或可能不会执行额外的 "rpm --checksig"。

安装介质的加密密钥

安装程序会愉快地自动找到其他安装源上的密钥并提供导入密钥。

但是,有趣的是,当您创建自己的安装介质时。 当安装开始时,RPM 数据库不可用以存储密钥,因此不会提供导入密钥的对话框。

要使您的公钥被接受为该源,就是将其与受信任的主密钥一起放置。

这些可以在“初始 ramdisk”aka“initrd”中找到,通常包含 /linuxrc 和用于在挂载 rootfs 之前加载的内核模块。

这些 initrd 可以在 UL 介质的 /boot/架构/loader/initrd(对于 x86 和 x86_64)或在 PowerPC 上的 /suseboot/initrd32 / initrd64 上找到。

要将您的新受信任密钥添加到 initrd,请执行以下操作(假设 $initrd 指向您的 initrd):

   gunzip <$initrd >$initrd.uncomp
   gpg --export -u $keyid > gpg-$keyid.gpg
   echo "gpg-$keyid.gpg" | cpio -o -H newc -A -F $initrd.uncomp
   gzip --best <$initrd.uncomp >$initrd
   rm $initrd.uncomp gpg-$keyid.gpg

这将解压缩 initrd,附加刚刚提取的公钥,然后重新压缩它。 对介质上找到的所有 initrd(有些有多个)执行此操作。

“repomd” 或 “YUM” 格式

这里我们使用相同的基本概念。 初始文件是 "repomd.xml",它再次使用分离的 GPG 签名在 "repomd.xml.asc" 中签名。

通常 repomd 仓库将用于更新和作为附加源,因此密钥已经为系统所知。 但是,您可以将用于签名 "repomd.xml.asc" 的 GPG 密钥对的公钥放在 "repomd.xml.key" 旁边。

如果您正在使用 RPM 密钥环中尚不存在的新密钥,系统会询问用户是否希望接受该密钥,然后注册仓库。

在 repomd.xml 和从那里引用的所有文件中,<checksum> 标签再次确保安装/更新源一致。 以下是一个示例片段

   
   <location href="repodata/patches.xml"/>
   <checksum type="sha">90ac427749079973d044a9398d6749f5f008</checksum>
   <timestamp>1144088097</timestamp>
   <open-checksum type="sha">90ac4044a9398d6749f5f008</open-checksum>
   

repomd 默认使用这些校验和。 我们添加的唯一一件事是对 "repomd.xml" 文件进行签名。

这很简单

      cd <repository directory>
      createrepo .
      gpg -a --detach-sign repodata/repomd.xml

您也可以使用 -b 代替 --detach-sign,因为它更短。

要直接提供您的 GPG 密钥与源

      gpg -a --export <your key id> > repodata/repomd.xml.key