pacman/软件包签名 - Arch Linux 中文维基

跳至內容

# pacman/软件包签名

出自 Arch Linux 中文维基
< Pacman

翻譯狀態：

- 本文（或部分內容）譯自 Pacman/Package signing，最近一次同步於 2022-10-27，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

相關文章

- GnuPG
- DeveloperWiki:Package signing

為了保證軟體包來自開發者, Pacman 使用信任網絡中的 GnuPG 密鑰進行軟體包驗證。這個網址記錄了 Archlinux 的主密鑰。其中至少三個主密匙被用來簽署官方開發者和授信用戶自己的密鑰，而他們將用這些密鑰簽署自己的包。用戶在配置 pacman-key 時也會生成一個唯一的密鑰。所以信任網絡也會把用戶的密鑰連接到五大主密鑰上面。

信任網絡示例:

- 自定義軟體包: 用戶自己構建軟體包並用本地密鑰簽名。
- 非官方軟體包: 開發者構建軟並簽名軟體包。用戶需要用自己的密鑰簽名開發者的密鑰，將其變為可信。
- 官方軟體包: 開發者構建軟體包，而開發者的密鑰已經被 Arch 主密鑰簽名。最終用戶用自己的密鑰簽名主密鑰，這樣就能信任所有官方開發者。

提示：HKP協議使用11371/tcp埠用來通信。為了從伺服器得到簽署的密鑰（使用pacman-key），這個埠必須打開。

## 配置

### 配置 pacman

`/etc/pacman.conf` 中的 `SigLevel` 配置用 `pacman -S` 安裝軟體時使用的檢查級別。文件的注釋中列出了幾個可選設置，pacman.conf(5) § PACKAGE AND DATABASE SIGNATURE CHECKING 有詳細介紹。簽名檢查可以全局配置或針對某個倉庫配置。如果 `SigLevel` 在 [options] 節中進行了全局設置，那麼所有的包都必須簽名。如果使用 `pacman.conf` 中默認的 `LocalFileSigLevel` ，所有編譯和用 `pacman -U` 安裝的軟體包都不需要使用 `makepkg` 進行簽名。

注意：儘管所有的官方軟體包現在都進行了簽名，但是在2018年11月的時候簽名資料庫還在開發。如果設置了 `Required` ，那麼 `DatabaseOptional` 也應該被設置。

默認的設置下，系統只安裝被授信的密鑰簽署的軟體包。

    /etc/pacman.conf

    SigLevel = Required DatabaseOptional

`TrustedOnly` 是 pacman 的默認設置。

默認配置的效果與下行等同：

    SigLevel = Required DatabaseOptional TrustedOnly

上面這些也可以在倉庫內部進行設置，比如：

    [core]
    SigLevel = PackageRequired # 』Optional』 here would turn off a global 』Required』 for this repository
    Include = /etc/pacman.d/mirrorlist

軟體倉庫中的軟體啟用了簽名驗證，但是並不要求倉庫資料庫也被簽名了。

警告：SigLevel `TrustAll` 設置僅僅為了測試而存在，使用它會信任未被驗證的密鑰。對於所有的官方軟體源你應該使用 `TrustedOnly` 。

### 初始化密鑰環

要初始化 pacman 密鑰:

    # pacman-key --init

    初始化密鑰，需要收集到足夠的熵。請隨意移動滑鼠，隨機按鍵盤或者運行一些磁碟讀寫操作（比如在其他終端運行ls -R /或者find / -name foo 或者 dd if=/dev/sda8 of=/dev/tty7之類的)應該會收集足夠的熵。如果你的系統沒有足夠的熵，這項工作需要好幾個小時，但是如果你有，那麼就會快多了。

這會在 `/etc/pacman.d/gnupg` 初始化密鑰並生成系統主密鑰。

注意：如果`pacman-key --init`運行時系統沒有足夠的熵，可能會需要很長時間。請在目標機器上安裝 haveged 或 rng-tools。然後在用 root 權限執行`pacman-key --init` 前啟動 `haveged.service`。

## 管理密鑰

### 驗證主密鑰

通過以下命令進行配置：

    # pacman-key --populate

該命令對 Master Signing Keys 進行驗證，when prompted as these are used to co-sign (and therefore trust) all other packager's keys.

PGP 通常很長(2048 位或更長)，不太容易使用，所以通常創建一個40位十六進制指紋，最後八位被稱為密鑰 ID，是密鑰的名字。長簽名可以用來檢測兩個密鑰是否相同。

### 官方開發者密鑰

官方開發者和 TU 的密鑰已經被主密鑰簽名認證，所以不需要用 pacman-key 認證它們。pacman 遇到不認識的簽名時，它將會詢問是否從密鑰伺服器（設置在`/etc/pacman.d/gnupg/gpg.conf`文件中，或在命令行中使用`--keyserver`選項）下載。

提示：維基百科提供了一份公鑰伺服器列表。

下載開發者密鑰後，以後都不需要下載。以後會用它驗證所有這個開發者構建的軟體包。

注意：

如果開發者和 TU 的密鑰是較早之前導入，它們的簽名可能還不存在於本地資料庫，用下面命令更新：

    # pacman-key --refresh-keys

當使用`--refresh-keys` 時，本地簽名也會被遠程查找，並收到未找到的消息，這是正常的。

### 導入非官方密鑰

可以通過此方法在pacman密鑰環中添加你自己的密鑰，或者啟用已簽名的非官方軟體倉庫。

首先從密鑰持有者手中拿到密鑰 ID(`keyid`)，然後把密鑰加入密鑰環：

- 如果密鑰位於密鑰伺服器，通過下面命令導入：

      # pacman-key -r keyid

- 如果提供了地址，先下載，然後用下面密鑰導入：

      # pacman-key --add /path/to/downloaded/keyfile

對於所有要簽名的密鑰，都通過指紋進行驗證：

    $ pacman-key -f keyid

最後，本地簽名導入的密鑰：

    # pacman-key --lsign-key keyid

現在可以用這個密鑰簽名軟體包了。

### 用GPG調試

如果需要，可以直接使用GPG調試pacman鑰匙環，例如：

    # gpg --homedir /etc/pacman.d/gnupg --list-keys

## 提示和技巧

### 定期升級系統

定期使用 pacman#升級軟體包更新系統可以防止絕大部分簽名錯誤。

#### 手動更新密鑰環

如果有時不可避免地在一段時間裡沒有更新系統，或者在安裝系統時使用的安裝映像版本較舊，可能會遇到密鑰環過舊而導致的簽名錯誤，提示為「文件簽名損壞」。這時你可以在更新系統之前手動同步包資料庫並升級 archlinux-keyring包：

    # pacman -Sy archlinux-keyring

此命令成功以後，應立即升級所有軟體包以避免部分升級：

    # pacman -Su

如果你是在安裝系統的過程中，可以跳過此 `pacman -Su` 命令，因為接下來將要運行的 `pacstrap` 命令會在新安裝的系統中安裝最新的軟體包。

這是唯一可以接受的使用 `-Sy` 升級軟體包而不被視為部分升級的情況。其餘情況下你總是應該使用 `pacman -Syu` 來升級系統。

### Update system time regularly

When the 系統時間 is faulty, signing keys could be considered expired (or invalid) and signature checks on packages will fail. Synchronize the system clock regularly by using the Network Time Protocol daemon.

## 問題解決

### error: signature from xxx is invalid

Pacman-key 依賴於系統時間。如果系統時間是錯誤的，將會獲得一個報錯：

    error: PackageName: signature from "User <email@archlinux.org>" is invalid
    error: failed to commit transaction (invalid or corrupted package (PGP signature))
    Errors occured, no packages were upgraded.

如果是使用 ntpd, (root權限) 執行 `ntpd -qg`，然後執行 `hwclock -w`.

如果使用的是其他 NTP 客戶端，請參考系統時間#時鐘同步。

如果問題依然存在，請嘗試下面方法：

### 刪除報錯的包

如果相同的包持續失敗，並且您確定 pacman-key 的相關操作是正確的，可以嘗試移除軟體包 `rm /var/cache/pacman/pkg/packagename` 或者清空所有緩存，然後可以重新下載軟體包。

### 重置所有密鑰

如果要刪除或重置系統，刪除 `/etc/pacman.d/gnupg` 目錄並重新運行 `pacman-key --init`。通過 `pacman-key --populate` 重新添加默認密鑰。

### 禁用簽名檢查

警告：小心使用，禁用簽名檢查，pacman 會自動安裝不信任的軟體包。

如果不在意軟體包簽名，可以完全禁用 PGP 簽名檢查，編輯 `/etc/pacman.conf` 並取消注釋 [options] 下的如下行:

    SigLevel = Never
     #LocalFileSigLevel = Optional
    #RemoteFileSigLevel = Required

需要同時注釋掉單獨軟體源的 SigLevel 設置，因為他們會覆蓋全局設置。

這樣就不會進行任何簽名檢查，和 pacman 4 之前一樣。如果這樣，就不需要用 pacman-key 建立密鑰環。

### 密鑰導入失敗

有三種可能的情況導致這個問題：

- 過期的archlinux-keyring包 包。
- 不正確的系統時間。
- 你的ISP屏蔽了用於導入 PGP keys 的埠。
- pacman 緩存中包含之前的未簽名軟體包
- 未正確設置 `dirmngr`

過期的 archlinux-keyring包 包可能會導致這個問題，根據情況採用下面的解決方法

#### 切換公鑰伺服器

如果這樣沒有起作用，並且系統時間是正確的，你可以嘗試切換到 Ubuntu 提供的公鑰伺服器(keyserver)。編輯 `/etc/pacman.d/gnupg/gpg.conf` 將 `keyserver` 行替換為

    keyserver hkp://keyserver.ubuntu.com

#### 清理軟體包緩存

如果上面方法都不起作用，pacman 緩存 `/var/cache/pacman/pkg/` 可以包含之前下載的未簽名軟體包，手動清空緩存：

    # pacman -Sc

    === Signature is unknown trust ===

在執行 `pacman -Syu` 時可能出現下面錯誤：

    error: package-name: signature from "packager" is unknown trust

這是因為 `package-name` 軟體包使用的 `packager` 的密鑰不被本地的 pacman-key gpg 資料庫信任。可能是密鑰在加入密鑰鏈之後失效了，可以通過下面方法解決：

- 用 `pacman-key --refresh-keys` 刷新密鑰
- 本地手動簽署密鑰
- 刷新所有密鑰
- 將 `SigLevel` 設置成 `TrustAll` (不推薦)

後面兩個選項將會破壞信任連，所以請謹慎使用。

### 通過代理更新密鑰

要使用代理更新密鑰，必須同時在 `/etc/gnupg/dirmngr.conf` 和 `/etc/pacman.d/gnupg/dirmngr.conf` 中設置 `honor-http-proxy` 選項。更多信息請閱讀 GnuPG#Use a keyserver.

注意：如果 pacman-key 沒有用 `honor-http-proxy` 選項，執行失敗，重啟可能能夠解決問題。

## 參閱

- DeveloperWiki:Package Signing Proposal for Pacman
- Pacman Package Signing – 1: Makepkg and Repo-add
- Pacman Package Signing – 2: Pacman-key
- Pacman Package Signing – 3: Pacman
- Pacman Package Signing – 4: Arch Linux

分類：​

- 包管理器

pacman/软件包签名
新增話題