投稿日:
更新日:

apt-key が非推奨になったので gnupg に移行する

Authors

目次

はじめに

Ubuntu 22.04 (LTS) がリリースされたのでインストールしてみましたが、そのまま放置して数ヶ月が経っていました。 久しぶりに 使用する場面が来たので、いつも通り apt update しようとしたところ、『Warning: apt-key is deprecated』というメッセージが表示されました。 どうやら、Debian 12 からは、apt パッケージの署名に利用している apt-key が非推奨・廃止になるとのことです。

しかし、今のところ、apt-key に変わる、apt リポジトリの署名に使用する GPG 公開鍵の管理手法におけるベストプラクティス的なものが無かったので、とりあえず、GnuPG (gnupg + signed-by) で移行してみました。

発生した事象

いつも通りapt updateをする。 すると、以下のようなメッセージが表示されました。 どうやら、apt リポジトリの公開鍵が欠落しているために署名を検証できず、パッケージリストの更新に失敗したようです。

$ sudo apt update
ヒット:1 http://jp.archive.ubuntu.com/ubuntu jammy InRelease
ヒット:2 http://jp.archive.ubuntu.com/ubuntu jammy-updates InRelease
エラー:1 http://jp.archive.ubuntu.com/ubuntu jammy InRelease
  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
ヒット:3 http://jp.archive.ubuntu.com/ubuntu jammy-backports InRelease
エラー:2 http://jp.archive.ubuntu.com/ubuntu jammy-updates InRelease
  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
エラー:3 http://jp.archive.ubuntu.com/ubuntu jammy-backports InRelease
  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
ヒット:4 https://packages.cloud.google.com/apt cloud-sdk InRelease
ヒット:5 https://dl.google.com/linux/chrome/deb stable InRelease
ヒット:6 https://packages.microsoft.com/ubuntu/22.04/prod jammy InRelease
ヒット:7 https://packages.microsoft.com/repos/vscode stable InRelease
ヒット:8 http://security.ubuntu.com/ubuntu jammy-security InRelease
エラー:5 https://dl.google.com/linux/chrome/deb stable InRelease
  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 4EB27DB2A3B88B8B
エラー:7 https://packages.microsoft.com/repos/vscode stable InRelease
  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY EB3E94ADBE1229CF
エラー:8 http://security.ubuntu.com/ubuntu jammy-security InRelease
  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了
状態情報を読み取っています... 完了
パッケージはすべて最新です。
W: 署名照合中にエラーが発生しました。リポジトリは更新されず、過去のインデックスファイルが使われます。GPG エラー: http://jp.archive.ubuntu.com/ubuntu jammy InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
W: 署名照合中にエラーが発生しました。リポジトリは更新されず、過去のインデックスファイルが使われます。GPG エラー: http://jp.archive.ubuntu.com/ubuntu jammy-updates InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
W: 署名照合中にエラーが発生しました。リポジトリは更新されず、過去のインデックスファイルが使われます。GPG エラー: http://jp.archive.ubuntu.com/ubuntu jammy-backports InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
W: 署名照合中にエラーが発生しました。リポジトリは更新されず、過去のインデックスファイルが使われます。GPG エラー: https://dl.google.com/linux/chrome/deb stable InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 4EB27DB2A3B88B8B
W: 署名照合中にエラーが発生しました。リポジトリは更新されず、過去のインデックスファイルが使われます。GPG エラー: https://packages.microsoft.com/repos/vscode stable InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY EB3E94ADBE1229CF
W: 署名照合中にエラーが発生しました。リポジトリは更新されず、過去のインデックスファイルが使われます。GPG エラー: http://security.ubuntu.com/ubuntu jammy-security InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
W: http://jp.archive.ubuntu.com/ubuntu/dists/jammy/InRelease の取得に失敗しました  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
W: http://jp.archive.ubuntu.com/ubuntu/dists/jammy-updates/InRelease の取得に失敗しました  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
W: http://jp.archive.ubuntu.com/ubuntu/dists/jammy-backports/InRelease の取得に失敗しました  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
W: http://security.ubuntu.com/ubuntu/dists/jammy-security/InRelease の取得に失敗しました  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 871920D1991BC93C
W: https://dl.google.com/linux/chrome/deb/dists/stable/InRelease の取得に失敗しました  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY 4EB27DB2A3B88B8B
W: https://packages.microsoft.com/repos/vscode/dists/stable/InRelease の取得に失敗しました  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY EB3E94ADBE1229CF
W: いくつかのインデックスファイルのダウンロードに失敗しました。これらは無視されるか、古いものが代わりに使われます
### Ubuntu のバージョンを確認
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.2 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

APT: Advanced Packaging Tool

普段から Ubuntu 等の Debian 派生の Linux を使用している人は当たり前のように aptコマンドを使用していると思います。 APT は Debian で採用されているパッケージ管理ツールであり、/etc/apt/sources.listというファイルに存在するパッケージインデックスファイルを取得して、/var/lib/apt/lists配下に保存します。

apt updateコマンドが実行されると、APT は、以下の手順に従って、パッケージを更新します。

  1. sources.listもしくは、sources.list.d (サードパーティ製リポジトリが格納されている場合が多い)に記録されている URL から InRelease ファイルをダウンロードする
  2. InRelease ファイルを、ローカルにあらかじめ保存しておいたリポジトリの公開鍵で検証する
  3. パッケージファイルをダウンロードする
  4. パッケージファイルのハッシュ値を、InRelease の中の情報で検証する
  5. パッケージのパスに応じてpool/main/等から、対象のパッケージファイルをダウンロードする
  6. ダウンロードしたパッケージファイルのハッシュ値を、パッケージファイルの中の情報で検証する

もし、2 の段階で保持しているリポジトリの公開鍵および KeyRing に、欠落・不整合等があった場合、上記のようなエラーが発生する。

そして、Debian 11 までは、パッケージの署名に使用している公開鍵をインポートする際には apt-key が使用されていました。

apt-key の仕組み

  • apt-key は APT KeyRing (デフォルトで/etc/apt/trusted.gpg.d) にリポジトリ鍵として GPG 公開鍵を登録・削除する
    • GPG (GNU Privacy Guard) : GPL に基づいた暗号化ソフト
  • ただし、実態は GPG の KeyRing そのものであり、GPG の鍵管理を行っているだけ
  • Ubuntu のインストール直後は Ubuntu の公式リポジトリとインストーラーイメージの鍵しか登録されていない
  • サードパーティ製のリポジトリを追加する場合、ここに新しい鍵が追加される
  • これにより、公開鍵が APT パッケージマネージャに信頼された KeyRing として追加され、正しく運用されているリポジトリであれば、公式リポジトリと同じように安全にパッケージをダウンロードできる

そんな便利な機能を提供してくれていた、apt-key ですが、apt 2.1.8 / Debian 11 から廃止予定 (deprecated⁠) となり、Debian 12 では削除されることになったらしいです...😭

廃止理由は、apt-key はなぜ廃止予定となったのか より

  • apt-key add は単一ファイル (/etc/apt/trusted.gpg) に鍵を追加していくため、複数のリスクの異なるリポジトリの鍵を同じ権限で管理しなくてはならない。

  • リポジトリ鍵として追加した鍵は、すべてのリポジトリに対して適用される。

APT のリポジトリ鍵は「リポジトリの管理者を信頼する」つまり「そのリポジトリサーバーが正しく運用されていることを期待する」前提に立っています。しかしながらリポジトリ鍵を /etc/apt/trusted.gpg.d/ に取り込んでしまうと、あるサードパーティのリポジトリに問題が発生したとき、その影響範囲がシステムにインストールされているすべてのパッケージに波及する可能性がある。

結局のところ/etc/apt/trusted.gpg.d/は、「⁠ システムで利用するすべてのリポジトリ」に対するチェックを行うための鍵を置く場所なので、リスクの異なるサードパーティのリポジトリの鍵も同じように扱うのはおかしい。

とのことらしい...。

実際に、apt-key listを実行すると、

$ apt-key list
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
/etc/apt/trusted.gpg
--------------------
pub   rsa4096 2018-09-17 [SC]
      F6EC B376 2474 EDA9 D21B  7022 8719 20D1 991B C93C
uid           [  不明  ] Ubuntu Archive Automatic Signing Key (2018) <ftpmaster@ubuntu.com>

pub   rsa4096 2016-04-12 [SC]
      EB4C 1BFD 4F04 2F6D DDCC  EC91 7721 F63B D38B 4796
uid           [  不明  ] Google Inc. (Linux Packages Signing Authority) <linux-packages-keymaster@google.com>
sub   rsa4096 2023-02-15 [S] [有効期限: 2026-02-14]
sub   rsa4096 2021-10-26 [S] [有効期限: 2024-10-25]

pub   rsa2048 2015-10-28 [SC]
      BC52 8686 B50D 79E3 39D3  721C EB3E 94AD BE12 29CF
uid           [  不明  ] Microsoft (Release signing) <gpgsecurity@microsoft.com>

警告メッセージが表示されました。

一応、バージョン確認。

### APT のバージョンを確認
$ apt --version
apt 2.4.9 (amd64)

### Debian のバージョンを確認
$ cat /etc/debian_version
bookworm/sid <- sid はDebianの非安定版 (unstable) を示す

なるほど。

リポジトリ鍵はどう運用すべきか

これまでは、apt-key add に渡していたリポジトリ鍵を、単に/etc/apt/trusted.gpg.d/に保存するだけというシンプルなものであった。 このときバイナリ形式なら拡張子として.gpgを使用し、ASCII 形式なら.ascを利用する。

よって次のような手順で、一旦適当な KeyRing に取り込んでからバイナリ形式でエクスポートするのが安全なよう。

$ gpg --no-default-keyring --keyring /tmp/temp-keyring.gpg --import [公開鍵.key]
$ gpg --no-default-keyring --keyring /tmp/temp-keyring.gpg --export --output [リポジトリ名.gpg]
$ rm /tmp/temp-keyring.gpg
$ sudo cp [リポジトリ名.gpg] /etc/apt/trusted.gpg.d/

しかし、この方法も、サードパーティのリポジトリに対するリスク管理という観点からは、完全な対応とは言えないらしい。

実際、Debian Wiki にあるサードパーティのリポジトリの利用に関するドキュメントでは、apt-key だけでなく/etc/apt/trusted.gpg.d/の利用も「MUST NOT⁠」の記述がある。

The certificate MUST be downloaded over a secure mechanism like HTTPS to a location only writable by root. The certificate MUST NOT be placed in /etc/apt/trusted.gpg.d or loaded by apt-key add.

そこで、OpenPGP certificate distribution と Sources.list entry に関するドキュメントを参考に GPG 公開鍵の KeyRing を/usr/share/keyrings/に設けて、配置することにする。

移行作業

作業手順

  1. 次のうちいずれかの方法で、/usr/share/keyrings/へ配置する
  • 新たに OpenPGP から公開鍵を取得してくるパターン
    • OpenPGP から公開鍵をインポートする
    • gnupgで KeyRing に変換して、/usr/share/keyrings/へ配置する
  • 既存の KeyRing から直接エクスポートするパターン
    • apt-key からエクスポートした鍵をgnupgで KeyRing に変換して、/usr/share/keyrings/へ配置する
  1. signed-byオプションでsources.listに紐付ける
  2. apt-key から削除する (/etc/apt/trusted.gpg.d/ディレクトリも消す)

まず、"不明" となっている以下の 3 つを検索する。

KEY ID (HEX)Repository
AF6ECB3762474EDA9D21B
7022871920D1991BC93C
Ubuntu Archive Automatic Signing Key
BEB4C1BFD4F042F6DDDCC
EC917721F63BD38B4796
Google Inc. (Linux Packages Signing Authority)
CBC528686B50D79E339D3
721CEB3E94ADBE1229CF
Microsoft (Release signing)

💡 A (Default) と B, C (Third party) で手順が異なるので、分けて書く。

(既に、apt-key に鍵が登録されていれば、② の方法で良いが、自分の場合、作業中の不手際で、A に関しては既存の KeyRing を消してしまったため、① の方法を取っている。)

【新たに OpenPGP から公開鍵を取得してくるパターン】Ubuntu Archive Automatic Signing Key の移行作業

  • 公開鍵を OpenPGP から取得する
$ cd [適当なディレクトリ]
$ curl 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xf6ecb3762474eda9d21b7022871920d1991bc93c' -o ubuntu-keyring-2018-archive.key
  • gnupgで KeyRing に変換して、/usr/share/keyrings/へ配置する
$ sudo gpg --no-default-keyring --keyring /usr/share/keyrings/ubuntu-keyring-2018-archive.gpg --import ubuntu-keyring-2018-archive.key
  • KeyRing を確認
$ file /usr/share/keyrings/ubuntu-keyring-2018-archive.gpg
/usr/share/keyrings/ubuntu-keyring-2018-archive.gpg: GPG keybox database version 1, created-at Wed Nov  2 13:11:23 2022, last-maintained Wed Nov  2 13:11:23 2022
  • signed-byオプションでsources.listに紐付ける
$ sudo vim /etc/apt/sources.list

signed-by=/usr/share/keyrings/ubuntu-keyring-2018-archive.gpg というオプションを追加する

# deb cdrom:[Ubuntu 21.10 _Impish Indri_ - Release amd64(20211024)]/ impish main restricted

# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
- deb http://jp.archive.ubuntu.com/ubuntu/ jammy main restricted
+ deb [arch=amd64 signed-by=/usr/share/keyrings/ubuntu-keyring-2018-archive.gpg] http://jp.archive.ubuntu.com/ubuntu/ jammy main restricted
# deb-src http://jp.archive.ubuntu.com/ubuntu/ impish main restricted

## Major bug fix updates produced after the final release of the
## distribution.
# deb-src http://jp.archive.ubuntu.com/ubuntu/ impish-updates main restricted

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
- deb http://jp.archive.ubuntu.com/ubuntu/ jammy universe
+ deb [arch=amd64 signed-by=/usr/share/keyrings/ubuntu-keyring-2018-archive.gpg] http://jp.archive.ubuntu.com/ubuntu/ jammy universe
# deb-src http://jp.archive.ubuntu.com/ubuntu/ impish universe
# deb-src http://jp.archive.ubuntu.com/ubuntu/ impish-updates universe

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## multiverse WILL NOT receive any review or updates from the Ubuntu
## security team.
- deb http://jp.archive.ubuntu.com/ubuntu/ jammy multiverse
+ deb [arch=amd64 signed-by=/usr/share/keyrings/ubuntu-keyring-2018-archive.gpg] http://jp.archive.ubuntu.com/ubuntu/ jammy multiverse
# deb-src http://jp.archive.ubuntu.com/ubuntu/ impish multiverse
# deb-src http://jp.archive.ubuntu.com/ubuntu/ impish-updates multiverse

## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
# deb-src http://jp.archive.ubuntu.com/ubuntu/ impish-backports main restricted universe multiverse
- deb http://security.ubuntu.com/ubuntu jammy-security main restricted
+ deb [arch=amd64 signed-by=/usr/share/keyrings/ubuntu-keyring-2018-archive.gpg] http://security.ubuntu.com/ubuntu jammy-security main restricted
# deb-src http://security.ubuntu.com/ubuntu impish-security main restricted
- deb http://security.ubuntu.com/ubuntu jammy-security universe
+ deb [arch=amd64 signed-by=/usr/share/keyrings/ubuntu-keyring-2018-archive.gpg] http://security.ubuntu.com/ubuntu jammy-security universe
# deb-src http://security.ubuntu.com/ubuntu impish-security universe
- deb http://security.ubuntu.com/ubuntu jammy-security multiverse
+ deb [arch=amd64 signed-by=/usr/share/keyrings/ubuntu-keyring-2018-archive.gpg] http://security.ubuntu.com/ubuntu jammy-security multiverse
# deb-src http://security.ubuntu.com/ubuntu impish-security multiverse

# This system was installed using small removable media
# (e.g. netinst, live or single CD). The matching "deb cdrom"
# entries were disabled at the end of the installation process.
# For information about how to configure apt package sources,
# see the sources.list(5) manual.
  • apt-key から削除する
### インポートした公開鍵を削除 (KeyRing に変換して配置したため、不要)
$ sudo rm -f ./ubuntu-keyring-2018-archive.key

### apt-key から削除
$ sudo apt-key del F6ECB3762474EDA9D21B7022871920D1991BC93C
OK

【既存の KeyRing から直接エクスポートするパターン】Google Inc. (Linux Packages Signing Authority) / Microsoft (Release signing) の移行作業

  • apt-key に登録されている既存の公開鍵の KEY ID を指定して、直接/usr/share/keyrings/へエクスポートする
$ sudo apt-key export EB4C1BFD4F042F6DDDCCEC917721F63BD38B4796 | sudo gpg --dearmour -o /usr/share/keyrings/google-chrome.gpg
$ sudo apt-key export BC528686B50D79E339D3721CEB3E94ADBE1229CF | sudo gpg --dearmour -o /usr/share/keyrings/microsoft.gpg
  • sources.list.dに登録する
$ sudo vim /etc/apt/sources.list.d/google-chrome.list
deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] https://dl.google.com/linux/chrome/deb/ stable main

$ sudo vim /etc/apt/sources.list.d/microsoft.list
deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft.gpg] https://packages.microsoft.com/repos/edge/ stable main
  • apt-key から削除
$ sudo apt-key del EB4C1BFD4F042F6DDDCCEC917721F63BD38B4796
OK

$ sudo apt-key del BC528686B50D79E339D3721CEB3E94ADBE1229CF
OK

確認

  • apt-key に何も登録されていないことを確認
$ apt-key list
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
  • 従来の KeyRing を削除
$ sudo rm -f /etc/apt/trusted.gpg
$ sudo rm -rf /etc/apt/trusted.gpg.d
  • apt update できることを確認
$ sudo apt update
ヒット:1 http://jp.archive.ubuntu.com/ubuntu jammy InRelease
ヒット:2 https://packages.cloud.google.com/apt cloud-sdk InRelease
取得:3 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
ヒット:4 https://packages.microsoft.com/repos/edge stable InRelease
取得:5 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [800 kB]
取得:6 http://security.ubuntu.com/ubuntu jammy-security/main amd64 c-n-f Metadata [9,144 B]
920 kB を 24秒 で取得しました (37.7 kB/s)
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了
状態情報を読み取っています... 完了
パッケージはすべて最新です。

以上の作業により、/etc/apt/trusted.gpg.d 配下に変換後の KeyRing を配置しなくても、正規のリポジトリからパッケージをインストールできるようになります。 これで、apt-key を使用せずに、信頼済みの署名鍵を使用してパッケージを確認できるようになります。

今後リポジトリ公開鍵を GPG KeyRing に追加する場合

【注意】 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys [KEY ID]は deprecated なのでもう使用しない!!

ex. google-cloud-sdkを追加する場合

  • 直接curlコマンドから取得した公開鍵を GPG KeyRing/usr/share/keyrings/にインポートする
$ curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --no-default-keyring --keyring /usr/share/keyrings/cloud.google.gpg --import
  • 確認
$ cat /etc/apt/sources.list.d/google-cloud-sdk.list
deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main

おわりに

今回は、apt-key が deprecated になってしまったので、KeyRing を自前で立てて、そちらに移行する方法について紹介しました。

Debian 11 (Bullseye) が apt-key が使える最後のリリースであり、Debian 12 (Bookworm) から完全に削除されてしまうので、早めに移行しておくことを強くお勧めします!

参考・引用