Ubuntu Weekly Recipe

第675回 apt-keyはなぜ廃止予定となったのか

この記事を読むのに必要な時間:およそ 5.5 分

サードパーティのAPTパッケージリポジトリを追加する際に使用する「apt-key」コマンドは,2020年8月の2.1.8から「廃止予定(deprecated⁠⁠」となり,2022年の半ばには削除される予定になりました。今回はその理由と,代替手段について解説しましょう。

リポジトリの正当性を担保する仕組み

Linuxにおけるパッケージ管理システムは,システムの重要なデータを置き換えるクリティカルな操作です。よってインターネットの先からパッケージをダウンロードする際は,その正当性を確認しなければなりません。⁠パッケージの正当性」と言ったとき,一般的には複数の意味が含まれます。

  1. パッケージに悪意のあるコードが含まれていないこと
  2. パッケージメンテナ以外の第三者が作ったパッケージがリポジトリにアップロードされていないこと
  3. 本来のリポジトリとは別の場所からパッケージをダウンロードしていないこと

まず一番気になる1についてですが,ここに関してはAPTによる保護の対象外です。利用者はそのパッケージのメンテナーを信頼することしかできません。言い換えると,PPAを含むサードパーティのリポジトリを登録する際は,便利かどうかだけでなく信頼できるかどうかも検討しましょう。

2も厳密にはAPTの対象外です。Ubuntuの公式リポジトリの場合は,ソースパッケージのアップロードにはメンテナーの署名が必要ですし,その署名を検証した上でビルドサーバーがパッケージをビルドし,適切な場所に配置します。しかしながら利用者の観点からすると,この部分についてもリポジトリの管理者を信頼する以外に手はありません。

APTで正当性を確認するのは,実質3のみです。正しい管理者が,悪意のあるコードを含まないパッケージをリポジトリにアップロードし正しく運用しているという前提のもと,ダウンロードしようとしているのが,その管理者によってアップロードされたパッケージであることを保証します。

この「正当性を保証」するために,APTの場合はGPGを利用した公開鍵方式で検証しています。バージョンや設定,リポジトリによって若干の差異はありますが,リポジトリからパッケージをダウンロードする際の検証方法は次のとおりです。

  1. sources.listに記録されているURLからInReleaseファイルをダウンロードする
  2. InReleaseファイルを,ローカルにあらかじめ保存しておいたリポジトリ鍵で検証する
  3. main/binary-amd64/PackagesなどのPackagesファイルをダウンロードする
  4. Packagesファイルのハッシュを,InReleaseの中の情報で検証する
  5. Packagesのパスに応じてpool/main/以下などから,対象のパッケージファイルをダウンロードする
  6. ダウンロードしたパッケージファイルのハッシュを,Packagesファイルの中の情報で検証する

InReleaseに対する署名は,リポジトリ鍵と対になる秘密鍵を持った人だけが可能です。つまりこれはリポジトリそのものの管理者であり,Ubuntuの公式リポジトリは「ftpmaster」と呼ばれます。このInReleaseの署名から続く検証の流れによって,ダウンロードしたパッケージファイルがリポジトリの管理者によるサイトからダウンロードしたことを確認できるわけです※1⁠。

※1
このあたりの情報はman apt-secureでも確認できます。

たとえばUbuntu 20.04 LTSのある日のInReleaseファイル※2は次のような内容になっています。

※2
InReleaseとは別にReleaseやRelease.gpgを使う場合もあります。Releaseが大本のデータで,Release.gpgはそれに対する署名情報です。InReleaseはReleaseとRelease.gpgをひとつにまとめたファイルInline signed Releaseです。またAPTが取得したInReleaseやReleaseファイルは/var/lib/apt/lists以下に保存されています。
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Origin: Ubuntu
Label: Ubuntu
Suite: focal
Version: 20.04
Codename: focal
Date: Thu, 23 Apr 2020 17:33:17 UTC
Architectures: amd64 arm64 armhf i386 ppc64el riscv64 s390x
Components: main restricted universe multiverse
Description: Ubuntu Focal 20.04
(中略)
 7ef83228ec207df10acac48fbdd81112          5826751 main/binary-amd64/Packages
(中略)
+m9MS1XP0RN13iWp3zXSlWJGPO/mDezqQ7vZ8Iwx
=7xQ1
-----END PGP SIGNATURE-----

Packagesも含むメタデータ情報のURLが示すコンテンツごとの,MD5SUM/SHA1/SHA256のハッシュ値を掲載しています。

それに対してリポジトリからダウンロードできる,Packagesファイル※3は上記のように,さまざまなハッシュ値を持った次のようなファイルになっています。

※3
リポジトリの特定のコンポーネントのすべてのパッケージ情報が含まれるため,公式リポジトリではxzやgzで圧縮されているものしか置かれていません。
Package: accountsservice
Architecture: amd64
Version: 0.6.55-0ubuntu13.2
Priority: standard
Section: gnome
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian freedesktop.org maintainers <pkg-freedesktop-maintainers@lists.alioth.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 452
Depends: dbus, libaccountsservice0 (= 0.6.55-0ubuntu13.2), libc6 (>= 2.4), libglib2.0-0 (>= 2.44), libpolkit-gobject-1-0 (>= 0.99)
Suggests: gnome-control-center
Filename: pool/main/a/accountsservice/accountsservice_0.6.55-0ubuntu13.2_amd64.deb
Size: 61424
MD5sum: 8d0c520e5edae8a0526a76982530ce2a
SHA1: 6859166c5c490cf4be3ce74dce3816bb56d4a5f0
SHA256: 344201d66fa1327b1dfce472dc062c5eba482f4caaecb1b832ec658869660b51
SHA512: 964b9ceef71c3cb3cf88dfda3344814c19030de01a59d514268bb2fa89d6495bf9bd587a44517aa960f71b06c04550d5fe9b9cfbd83840e06179708adc4e85cf
Homepage: https://www.freedesktop.org/wiki/Software/AccountsService/
Description: query and manipulate user account information
Task: standard
Description-md5: 8aeed0a03c7cd494f0c4b8d977483d7e

Package: acct
Architecture: amd64
(後略)

そしてaccountsservice_0.6.55-0ubuntu13.2_amd64.debは,上記で列挙されているハッシュ値で検証することで,正当性を確認できるわけです。これによりUbuntuのリポジトリは,HTTPSなどを使わなくても中間者攻撃の心配をする必要なくパッケージをダウンロードできます※4⁠。

※4
特に公式リポジトリやそのミラーリポジトリはストレージ・ネットワーク負荷が高いためおいそれとはHTTPS化できませんし,上記のような仕組みの結果としてHTTPS化する意味も今のところあまりありません。ただしリポジトリの公開鍵の配布なども合わせて行う場合は,HTTPS化は必須です。ちなみにお行儀の悪いプロキシーが間に挟まると,上記のメタデータとハッシュの対応に齟齬が生じ,⁠apt update」などで「ハッシュサムが適合しません」などのエラーが出てパッケージの更新が失敗します。このあたりの対応については第331回のパッケージ管理のハウツー集も参照してください。

ここでポイントになってくるのが,InReleaseの署名を検証するための「リポジトリ鍵」です。リポジトリの管理者が秘密鍵を使ってInReleaseを署名するとして,利用者はその公開鍵を何らかの方法で取得・管理しなくてはなりません。Ubuntuの公式リポジトリについては,⁠インストーラーに組み込む」ことで自動的に登録されます。これはubuntu-keyringパッケージとして提供されています。

$ gpg --list-keys --keyring /etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg
/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg
------------------------------------------------------
pub   rsa4096 2018-09-17 [SC]
      F6ECB3762474EDA9D21B7022871920D1991BC93C
uid           [  不明  ] Ubuntu Archive Automatic Signing Key (2018) <ftpmaster@ubuntu.com>

たとえばInReleaseファイルをダウンロードして検証してみましょう。

$ wget http://jp.archive.ubuntu.com/ubuntu/dists/focal/InRelease
$ gpgv --keyring /etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg InRelease
gpgv: 2020年04月24日 02時34分17秒 JSTに施された署名
gpgv:                RSA鍵3B4FE6ACC0B21F32を使用
gpgv: 署名を検査できません: 公開鍵がありません
gpgv: 2020年04月24日 02時34分17秒 JSTに施された署名
gpgv:                RSA鍵871920D1991BC93Cを使用
gpgv: "Ubuntu Archive Automatic Signing Key (2018) <ftpmaster@ubuntu.com>"からの正しい署名

鍵「3B4FE6ACC0B21F32」は2018年より前に使われていた鍵です。古いリリースのUbuntuでも検証できるように,古い鍵でも署名されています。

このようにAPTによるパッケージの正当性は,リポジトリ鍵に依存する仕組みになっています。そのリポジトリ鍵を管理するのがapt-keyコマンドだったのです。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。