

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 AL2023 中对存储库元数据进行签名 AL2023
<a name="repo-metadata-signing"></a>

从发行版开始`2023.11.20260406`，AL2023 存储库包括存储库元数据的加密签名。AL2023 每个存储库`repomd.xml`的文件都附有一个分离的 GPG 签名文件 (`repomd.xml.asc`)，您可以在下载软件包之前使用该文件来验证存储库元数据的真实性和完整性。

此签名是对现有 RPM 包签名 (`gpgcheck`) 的补充，后者可以验证各个软件包。存储库元数据签名验证描述存储库内容的元数据，例如可用软件包列表及其校验和。

Package 签名可以保护每个包裹。否则，列出这些软件包的元数据索引仅基于 TLS 和校验和受信任。如果索引上没有签名，受感染的镜像或传输路径可能会提供经过修改的元数据，从而隐藏或阻止安全更新。存储库元数据签名填补了这一差距，并且不依赖镜像或传输信任。

## 仓库元数据签名的工作原理
<a name="repo-metadata-signing-overview"></a>

发布 AL2023 存储库时，将使用AWS KMS 密钥对存储库元数据 (`repomd.xml`) 进行签名。AL2023 生成的分离签名 (`repomd.xml.asc`) 放在存储库中的元数据旁边。

当您在存储库配置`repo_gpgcheck`中启用时，在使用存储库元数据之前，将根据 GPG 公钥DNF验证`repomd.xml.asc`签名。如果验证失败，则DNF拒绝元数据，并且不会从该存储库运行包操作。

首次DNF验证存储库的元数据时，它会提示您将该存储库的签名密钥导入到每个存储库的密钥环中。此提示默认为`No`。如果您拒绝，则DNF跳过存储库。有关的更多信息`repo_gpgcheck`，请参阅《[DNF配置参考](https://dnf.readthedocs.io/en/latest/conf_ref.html)》。

这与已经用于包验证的密钥相同，但将其DNF存储在单独的密钥环中以进行元数据检查。即使密钥已在磁盘上，系统仍会提示您进行确认。这是预期的DNF行为。

以下 AL2023 存储库包含已签名的元数据：AL2023
+ 核心存储库 (`amazonlinux`)
+ 内核 Livepatch 存储库 () `kernel-livepatch`
+ NVIDIA 存储库 (`amazonlinux-nvidia`)
+ 亚马逊 Linux 存储库的补充软件包 (`amazonlinux-spal`)

## `gpgcheck 和 re po_gpgcheck 的区别`
<a name="repo-metadata-signing-gpgcheck-vs-repo-gpgcheck"></a>


| 设置 | 它验证了什么 | AL2023 中的默认值 AL2023 | 
| --- | --- | --- | 
| gpgcheck=1 | 安装前验证各个 RPM 软件包的 GPG 签名。 | 已启用 | 
| repo\_gpgcheck=1 | 在使用存储库之前，请验证存储库元数据 (repomd.xml) 的 GPG 签名。 | 默认情况下禁用 | 

我们建议您在确认自动化准备就绪后`repo_gpgcheck`，同时启用`gpgcheck`和。这会在使用前验证存储库元数据和各个软件包。在启用之前`repo_gpgcheck`，请参阅[在自动化中使用存储库元数据验证](#repo-metadata-signing-automation)。

## 启用仓库元数据验证
<a name="repo-metadata-signing-enable"></a>

您可以通过更新各个存储库的配置文件来为其启用存储库元数据验证。

**重要**  
默认情况下，存储库元数据签名验证未启用。在您更改它之前，它会一直处于禁用状态。在启用它之前，请确认自动化中的每个无人值守DNF命令都通过了该`-y`选项。有关更多信息，请参阅 [在自动化中使用存储库元数据验证](#repo-metadata-signing-automation)。

### 为特定存储库启用
<a name="repo-metadata-signing-enable-per-repo"></a>

默认情况下，已`/etc/yum.repos.d/`设置 `repo_gpgcheck=0` AL2023 存储库配置文件。AL2023 要启用存储库元数据验证，请在存储库配置`1`中将此值更改为。例如，要为核心存储库启用它，请执行以下操作：

```
[amazonlinux]
name=Amazon Linux 2023 repository
...
gpgcheck=1
repo_gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-2023
```

### 禁用仓库元数据验证
<a name="repo-metadata-signing-disable"></a>

要恢复之前的行为，请在存储库配置文件`repo_gpgcheck=0`中进行设置。下一次元数据刷新无需验证即可成功。

```
[ec2-user ~]$ sudo sed -i 's/^repo_gpgcheck=1/repo_gpgcheck=0/' /etc/yum.repos.d/amazonlinux.repo
[ec2-user ~]$ sudo dnf -y makecache
```

## 验证存储库元数据签名是否正常工作
<a name="repo-metadata-signing-verify"></a>

启用后`repo_gpgcheck=1`，您可以通过清除DNF缓存并刷新元数据来验证元数据验证是否正常工作：

```
[ec2-user ~]$ sudo dnf clean metadata
[ec2-user ~]$ sudo dnf makecache
```

首次DNF验证存储库的元数据时，它会提示您导入该存储库的签名密钥。输入 `y`以确认。导入密钥后，DNF创建没有错误的元数据缓存。可以看到类似以下内容的输出：

```
Amazon Linux 2023 repository                    1.7 MB/s | 1.8 kB     00:00
Importing GPG key 0xD832C631:
 Userid     : "Amazon Linux <amazon-linux@amazon.com>"
 Fingerprint: B21C 50FA 44A9 9720 EAA7 2F7F E951 904A D832 C631
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-2023
Is this ok [y/N]: y
Amazon Linux 2023 repository                      18 MB/s |  55 MB     00:03
Metadata cache created.
```

导入提示默认为`No`。如果您拒绝，则DNF跳过存储库并在输出`Ignoring repositories`中报告。如果验证失败，则DNF报告 GPG 签名错误并且不会创建缓存。

有关无人值守的运行，请参阅[在自动化中使用存储库元数据验证](#repo-metadata-signing-automation)。

## 在自动化中使用存储库元数据验证
<a name="repo-metadata-signing-automation"></a>

**注意**  
密钥导入提示默认为`No`。无人值守DNF运行无法回答提示，因此它会拒绝导入并跳过存储库。由于 AL2023 已设置`skip_if_unavailable=True`，因此该命令仍以状态`0`退出。AL2023 因此，在主机未收到任何软件包或更新的情况下，自动化会报告成功。输出`Ignoring repositories`中显示了这个标志。

为防止这种情况，请将该`-y`选项传递给每个刷新元数据的无人值守DNF命令，包括持续集成作业、映像和容器构建`cloud-init`、配置管理以及 cron 作业。

```
[ec2-user ~]$ sudo dnf -y makecache
[ec2-user ~]$ sudo dnf -y check-update
[ec2-user ~]$ sudo dnf -y upgrade
```

刷新元数据的命令需要`-y`。只读取本地缓存或本地 RPM 数据库的命令，或者使用该`-C`选项的命令不会刷新元数据，也不会提示。完整列表请参阅 [刷新存储库元数据的命令](#repo-metadata-signing-command-reference)。

永久`-y`保持自动化。每个存储库 URL 的密钥导入一次，而不是每个主机导入一次。AL2023 根据锁定版本 (`releasever`) 和AWS区域构建每个存储库 URL，因此操作系统版本升级或区域更改会解析为新 URL 并再次提示。AL2023 签名密钥不会改变；只有它的密钥环位置会改变。不要将密钥作为一次性修复进行预设或预先烘烤，因为下一版本升级或 Region 会使用新的密钥环并再次提示。

运行会`dnf clean all`清除缓存的元数据，但不会移除同一版本中导入的密钥。它不会重新触发提示。

容器镜像构建需要特别注意。映像构建中的每个`RUN dnf`步骤都是无人值守的，而且密钥环是图像文件系统的一部分，因此在每个新映像中，密钥环都是空的。无论你正在运行的主机已经导入了什么，都会在构建过程中出现提示。传`-y`入映像构建。

**注意**  
如果您以 Python 库 (`import dnf`) 的DNF形式驱动，则提示不适用。该库在不提示的情况下导入密钥，因此无需提示即可`-y`加载元数据。

## 刷新存储库元数据的命令
<a name="repo-metadata-signing-command-reference"></a>

任何下载或刷新存储库元数据的命令都会触发密钥导入和提示。只读取本地缓存或本地 RPM 数据库的命令不会。选项会更改结果：例如，`-v`进行`repolist`获取、`--installed`保留`list`和`info`本地化，`-C`或者`--cacheonly`避免获取并`--refresh`强制执行。如有疑问，请通过`-y`。


| 命令 | 刷新元数据 | 
| --- | --- | 
| dnf makecache | 支持 | 
| dnf check-update | 是 | 
| dnf upgrade, dnf update | 是 | 
| dnf upgrade-minimal | 是 | 
| dnf distro-sync | 是 | 
| dnf install | 是 | 
| dnf reinstall | 是 | 
| dnf downgrade | 是 | 
| dnf autoremove | 是 | 
| dnf swap | 是 | 
| dnf list（默认值或--available） | 是 | 
| dnf info（默认值或--available） | 支持 | 
| dnf search | 是 | 
| dnf provides | 是 | 
| dnf repoquery | 是 | 
| dnf repoinfo | 是 | 
| dnf deplist | 是 | 
| dnf repository-packages | 是 | 
| dnf updateinfo | 是 | 
| dnf group（列表、信息、安装） | 是 | 
| dnf module（列表、信息） | 是 | 
| dnf shell（如果它的子命令获取） | 支持 | 
| dnf builddep | 是 | 
| dnf changelog | 是 | 
| dnf debuginfo-install | 是 | 
| dnf download | 是 | 
| dnf repoclosure | 是 | 
| dnf repograph | 是 | 
| dnf reposync | 是 | 
| dnf debug-dump | 是 | 
| dnf repolist -v（详细） | 是 | 
| dnf repolist（纯色或--all） | 否 | 
| dnf list --installed, dnf info --installed | 否 | 
| dnf remove, dnf erase | 否 | 
| dnf mark | 否 | 
| dnf history | 否 | 
| dnf check | 否 | 
| dnf clean | 否 | 
| dnf config-manager | 否 | 
| dnf needs-restarting | 否 | 
| dnf alias | 否 | 
| dnf help | 否 | 
| dnf repomanage | 否 | 
| dnf repodiff | 否（除非命名了两个存储库，否则会出错） | 
| dnf copr | 否 | 
| dnf groups-manager | 否 | 
| dnf playground | 否 | 
| dnf debug-restore | 否（对已保存的转储执行操作） | 
| 任何带有-C或的命令 --cacheonly | 否 | 

输出中报告了以这种方式跳过的存储库，但由于 AL2023 已设置`skip_if_unavailable=True`，这些命令`Ignoring repositories`中的大多数仍以状态`0`退出。AL2023 不要仅仅依赖退出代码。通过`-y`，密钥导入成功。

## 检测已跳过的存储库
<a name="repo-metadata-signing-detect"></a>

仅凭退出代码并不能确认验证成功。跳过的存储库将退出`0`，并且一旦运行导入签名密钥，签名密钥就会保留，因此稍后的检查可以通过，而前面的步骤仍然失败。请改用以下两项检查：
+ 审核您的自动化。确认所有元数据获取命令均已通过DNF。`-y`这就是让你继续研究下一个新存储库 URL 的原因。
+ 检查输出`Ignoring repositories`。跳过存储库时，以下命令将失败，您可以使用该命令使管道失败：

```
[ec2-user ~]$ sudo dnf makecache 2>&1 | grep -q "Ignoring repositories" && { echo "repo skipped"; exit 1; }
```

## 固定版本
<a name="repo-metadata-signing-pinned"></a>

如果您将`releasever`（使用`--releasever``/etc/dnf/vars/releasever`、或`dnf.conf`）固定到之前发布的版本`2023.11.20260406`，则该版本没有签名文件，并且`repo_gpgcheck=1`无法刷新存储库：

```
Error: Failed to download metadata for repo 'amazonlinux':
GPG verification is enabled, but GPG signature is not available...
```

固定的版本不会收到超过该版本的更新。如果您固定，请固定到版本`2023.11.20260406`或更高版本，或者进行设置`repo_gpgcheck=0`。

## AL2023 存储库的 GPG 公钥 AL2023
<a name="repo-metadata-signing-gpg-keys"></a>

用于存储库元数据验证的 GPG 公钥由相应的存储库配置 RPM 安装到。`/etc/pki/rpm-gpg/`下表列出了每个存储库使用的公钥。


| Repository | Package 签名密钥 | Repodata 签名密钥 | 分布在 | 
| --- | --- | --- | --- | 
| 核心 (amazonlinux) | RPM-GPG-KEY-amazon-linux-2023 | RPM-GPG-KEY-amazon-linux-2023 | system-release | 
| 内核 LivePatch () kernel-livepatch | RPM-GPG-KEY-amazon-linux-2023 | RPM-GPG-KEY-amazon-linux-2023 | system-release | 
| 英伟达 (amazonlinux-nvidia) | RPM-GPG-KEY-NVIDIA-D42D0685 | RPM-GPG-KEY-amazon-linux-2023-nvidia | nvidia-release | 
| SPAL () amazonlinux-spal | RPM-GPG-KEY-amazonlinux-spal | RPM-GPG-KEY-amazonlinux-spal | spal-release | 

当您安装相应的存储库配置 RPM 时，会自动安装这些密钥。