Ubuntu Weekly Recipe

第677回aptで使うsources.listのオプションいろいろ

第675回ではapt-keyコマンドが廃止される理由を、さらに第676回ではaptの新機能を紹介しました。今回はaptパッケージのリポジトリ情報を指定するsources.listの内容とそのカスタマイズ方法について紹介しましょう。

リポジトリ情報を設定するsources.list

Aptはリポジトリにあるパッケージをその依存関係に基づいてダウンロードし、システムにインストールするツールです。その「リポジトリ」の情報を管理するのがsources.listと呼ばれるファイルとなります。

パッケージリポジトリとしてアクセスするためには、具体的には次の情報が必要です。

  • リポジトリのURI
  • 通信プロトコルの種別
  • リリース名やコンポーネント
  • アーキテクチャーや鍵情報など、その他のオプション

これらの情報が/etc/apt/sources.listもしくは/etc/apt/sources.list.d/以下のファイルに保存されます。

Ubuntuの場合は、Ubuntu公式のリポジトリ情報を/etc/apt/sources.listに記述し、サードパーティの情報は/etc/apt/sources.list.d/以下に「なんとか.list」というファイル名で保存するのが一般的です。sources.list.d以下のファイル名は、英数字a-zA-Z0-9およびアンダースコア_⁠、ハイフン-⁠、ピリオド.のみ含めることができます。またファイル名は.listで終わっている必要があります[1]⁠。

すべてsources.listにまとまっていると管理が大変になるので、サードパーティのリポジトリを追加する場合は、なるべくsources.list.dを利用しましょう。ここではどちらもまとめて「sources.list」と呼称します。

1行スタイルのフォーマット

sources.listは、古い書式だと次のようなフォーマットで記述します。

deb [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]
deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]

「古い書式」というからには「新しい書式」もあるのですが、こちらはまだあまり使われていません。新しい書式(deb822)については後半で説明します。

古い書式では、リポジトリごとに1行ずつ記述します。空行および#で始まる行は無視されます。行の途中に#がある場合は、その行のそれ以降の内容を無視します。URIに#がある場合などはURLエンコードを使うよう、注意してください。

「deb」で始まるのはバイナリパッケージ、⁠deb-src」で始まるのはソースパッケージを提供するリポジトリです。普段使う分には、バイナリパッケージだけで十分です。ソースパッケージリポジトリを有効化するとその分だけダウンロードするメタデータの情報なども増えてしまいます。パッケージングなど特別な理由がない限りはdeb-srcを有効化しなくて良いでしょう。

ちなみに/etc/apt/sources.listには最初から公式リポジトリのソースパッケージ行がコメントアウトされています。デスクトップ版だと「ソフトウェアとアップデート」から有効化できますし、手作業で行頭の#を削除してコメントアウトを無効化すれば、ソースパッケージをダウンロードできるようになります。

リポジトリのオプションとURI

[ option1=value1 option2=value2 ]でリポジトリごとの固有のオプションを指定できます。普段使うことはないのですが、特定の条件下ではオプションを使うと便利なこともあります。オプションの種別については後ほど説明します。

uriがリポジトリのURIを指定する部分です。Ubuntuの公式リポジトリの日本のミラーサーバーだとhttp://jp.archive.ubuntu.com/ubuntu/となりますし、Debianの日本のミラーサーバーだとhttp://ftp.jp.debian.org/debian/を指定することが一般的です。また、HTTP以外のプロトコルでアクセスすることもあります。URIの指定方法についても詳細は後述します。

ディストリビューションごとに異なるsuiteとcomponent

suitecomponentはリポジトリ固有の設定です。

suiteには一般的に「リリースのコードネーム」が使われます。たとえばUbuntu 20.04 LTS(Focal Fossa)だと「focal」ですし、21.04(Hirsute Hippo)だと「hirsute」です。さらにリリース後のアップデートを提供するfocal-updatesやそのうちセキュリティアップデートのみ提供するfocal-securityなども存在します。Debianの場合は「buster(Debian 10⁠⁠」や「bullseye(Debian 11⁠⁠」を指定することもありますが、よりジェネリックな「stable(最新の安定版⁠⁠sid(開発版⁠⁠」といった名前を使うこともあります。

コードネームを指定する場合は、一般的に「URI/dists/SUITE/」のアドレスへ、aptコマンドがメタデータファイルを取得しにいきます。Ubuntuのfocalならhttp://jp.archive.ubuntu.com/ubuntu/dists/focal/です。apt updateを実行すると、各リポジトリのInReleaseファイルないしReleaseRelease.gpgファイルを所得するのです。

suiteはファイルパスを直接指定することもあります。これはInReleasePackagesといったメタデータが同じディレクトリに存在する場合に有効です。なおファイルパスを指定する場合は、componentは指定できません。

componentはそのリポジトリが複数のコンポーネントに対応しているときに有効なオプションです。たとえばUbuntuの場合、そのサポートやライセンスに応じてリポジトリごとにmain、restricted、universe、multiverseの4種類にわかれています。Debianにもmain、contrib、non-freeが存在します。公式リポジトリのようにコンポーネントに対応したリポジトリを使う場合は、componentを適切に設定しましょう。複数を同時に設定することも可能ですし、コンポーネントだけ変更してURIやsuiteは同じ行を複数行設定することも可能です。

ここまででsources.listの基本的な設定は把握できました。これにより個々の行の意味をおおよそ理解できるはずです。次は個別の設定項目について、設定できる選択肢を見ていきましょう。

URIの指定方法

URIは「スキーム:アドレス」の形で指定します。最新のAptでサポートしているスキームは次のとおりです。

http
もっとも一般的なHTTPを使うスキームです。⁠http://アドレス/」の形で指定できます。アドレス部分は単なるドメイン名だけでなく「アドレス:ポート」のようなポート番号指定や、⁠ユーザー名:パスワード@アドレス」のようなBASIC認証情報の付加も可能です。ただし認証情報については、ここには記述せずにapt_auth.confを使うべきでしょう。もちろんHTTP接続なので、認証情報は暗号化されません。apt.confにはプロキシーや接続に関するHTTPに関するより詳細な設定を記述できます。
https
通信にHTTPSを利用します。Apt 1.6より前(つまりUbuntu 17.10以前)はHTTPSを使うためにapt-transport-httpsパッケージが必要でしたが、現在はaptパッケージだけでHTTPS通信が可能です。基本的な部分はhttpスキームと同じで、利用するルート証明書等の設定が追加されています
mirror

リポジトリそのもののURIではなく、リポジトリとして利用できるミラーサーバーのURIのリストを記録したファイルの場所を指定できます。たとえば「mirror://example.com/mirror.list」を指定した場合は、example.comのmirror.listの中にあるミラーサーバーをランダムに選択し、それをリポジトリのURIとして利用します。うまく接続できない場合は、同じファイルの別のURIにフォールバックします。

ローカルシステム内部で管理しているミラーリストを参照したい場合は「mirror+file:/etc/apt/mirror.list」のように「mirror+scheme」フォーマットでスキームを指定できます。ミラーリストは単にURIを1行ごとに書いたファイルです。さらに、プライオリティも含むいくつかのオプションも指定可能です
fileとcopy

fileおよびcopyはともにローカルシステム内の任意のディレクトリをリポジトリとして参照できるスキームです。⁠file:///path/」のように指定します。マウントされてさえいれば、バックエンドのアクセス方法は問わないため、NFSやその他のネットワークファイルシステムも利用可能です。

copyはhttpなどと同じように一旦キャッシュディレクトリ/var/cache/apt/以下にファイルをダウンロードした上で、インストールを実施します。
cdrom
光学メディアやUSBストレージのようにリムーバブルなデバイスを指定する際に利用するスキームです。⁠cdrom:ラベル」のようなフォーマットで指定します。Liveブートした環境だと設定されており、ネットワークがない環境でパッケージをアップデートしたい際などに利用します。ただし単に外部ストレージをリポジトリとして使いたいだけなら、fileでも実現可能です。cdromスキームについてはapt-cdromコマンド等と併用して使うことになるでしょう。
ftp、rsh、ssh
FTP/RSH/SSHなどを利用してサーバーに接続しファイルをダウンロードします。アカウント情報や鍵等の設定が必要です。特別な環境でない限りは使われることはあまりないでしょう。

Aptは/usr/lib/apt/methodsにファイルを置くことで、スキームを拡張できる仕組みが存在します。サードパーティによる拡張は「apt-transport-FOO」という名前でパッケージ化されていますので、実際に探してみると良いでしょう。とはいえ現在存在するのは、AWS S3をリポジトリとして使えるapt-transport-s3やTorでアクセスできるapt-transport-torin-totoという仕組みでパッケージを取得できるapt-transport-in-totoぐらいです。

URIにはミラーリポジトリを指定できます。たとえばUbuntuの公式リポジトリは「archive.ubuntu.com」ですが、日本の公式ミラーサーバーとして「jp.archive.ubuntu.com」も利用可能です[2]⁠。

ちなみにarm64やarmhfなどamd64以外のアーキテクチャーパッケージについては、ports.ubuntu.comで提供されています。こちについては「公式のミラーサーバー」は用意されていないため、Raspberry Piなどでは原則として「ports.ubuntu.com」を指定することになります。

Ubuntuの場合、サポート期間が終了すると(End of Lifeを迎えると⁠⁠、そのリポジトリは使えなくなります。たとえば先日、Ubuntu 20.10のサポートが終了しました。よって20.10のリポジトリデータにはまもなくアクセスできなくる見込みです[3]⁠。しかしながらやむにまやれに理由により、EOLを迎えたUbuntuをインストールし、状況によってはaptコマンドでパッケージをインストールする必要が出てくることもあるでしょう。そんな用途向けに、old-releases.ubuntu.comが存在します。

これは古いリリースのリポジトリやインストールメディアを提供するサイトです。sources.listの「jp.archive.ubuntu.com」「old-releases.ubuntu.com」へと置き換えれば、サポート終了後のリリースであってもパッケージのアップデートやインストールが可能になります。

当然のことながら、これらのリポジトリにはサポート期間終了後のセキュリティアップデートは提供されていません。これらリポジトリを有効化したマシンでインターネットに直接接続することは、危険な行為であることを理解した上で利用してください。

各種オプション

sources.listにはdeb/deb-srcとURIの間に[ option1=value1 option2=value2 ]のようなフォーマットで、複数のオプションを指定可能です。便利なものをいくつか紹介しましょう。

arch=amd64,arm64のように指定すると、そのリポジトリで利用するアーキテクチャーを指定できます。指定しない場合はシステム全体の設定に依存し、amd64なマシンなら「amd64」「i386」を、Raspberry PiのようなARMマシンで32bitなら「armhf⁠⁠、64bitなら「arm64」が使われます。たとえば「特定のリポジトリはi386のパッケージ情報だけあれば十分」といった場合に便利なオプションです。

trusted=yesを設定すると、リポジトリの署名検証を迂回できます。つまりそのリポジトリを全面的に信用します。ローカルリポジトリのようにパッケージの署名作業をスキップしたい場合に便利です。言い方を変えると「本当に信頼できるパッケージしか置いていないリポジトリ」以外では指定してはいけません。

signed-by=鍵名では、リポジトリの検証時に利用する鍵をフィンガープリントもしくはファイルパスで指定します。特定のサードパーティのリポジトリでは、そのサードパーティが提供する鍵を利用します。リポジトリの署名に関しては第675回のapt-keyはなぜ廃止予定となったのかを参照してください。

deb822スタイルフォーマット

Apt 1.1以降は、これまで説明した1行フォーマットとは別に「deb822スタイルフォーマット」と呼ばれる形式でもsources.listを記述できるようになりました。

deb822とは電子メールのメッセージフォーマットとして策定された「RFC 822」をベースにしたフォーマットで、Debianパッケージのメタデータなどで使われています。簡単に説明すると、パッケージの情報を「フィールド名: 値」で記述し、空行でリポジトリを区切ります。たとえばUbuntuのリポジトリの情報は1行フォーマットだと次のように記述します。

deb http://jp.archive.ubuntu.com/ubuntu/ focal main restricted
deb-src http://jp.archive.ubuntu.com/ubuntu/ focal main restricted
deb http://jp.archive.ubuntu.com/ubuntu/ focal-updates main restricted
deb-src http://jp.archive.ubuntu.com/ubuntu/ focal-update main restricted

これがdeb822だと次のように変換されます。

Types: deb
URIs: http://jp.archive.ubuntu.com/ubuntu
Suites: focal
Components: main restricted

Types: deb-src
URIs: http://jp.archive.ubuntu.com/ubuntu
Suites: focal
Components: main restricted

Types: deb
URIs: http://jp.archive.ubuntu.com/ubuntu
Suites: focal-updates
Components: main restricted

Types: deb-src
URIs: http://jp.archive.ubuntu.com/ubuntu
Suites: focal-updates
Components: main restricted

また、上記の例だともっとシンプルに1ブロックで記述可能です。

Types: deb deb-src
URIs: http://jp.archive.ubuntu.com/ubuntu
Suites: focal focal-updates
Components: main restricted

deb822の採用によって、sources.listより機械的に読み取りやすく、人間も理解しやすいフォーマットになります。またフィールドを追加すれば良いだけなので、拡張性も高くなります。

なお、deb822フォーマットの場合はファイルの拡張子も.listではなく.sourcesになります。#でコメントを記述できるのはdeb822も同じです。ちなみに1行フォーマットの場合、そのリポジトリを無効化するにはコメントアウトするかその行を削除するしか方法はありませんでした。deb822の場合Enabled: noを追加することでも、リポジトリを無効化できます。

ただしパッケージに関するすべてのソフトウェアがこのフォーマットをサポートしているわけではありません。Ubuntuで標準的に利用するソフトウェアならほぼ問題ないはずですが、場合によってはまだ未対応のこともあるかもしれませんので注意してください[4]⁠。

ローカルリポジトリの作り方

真っ当なAptのリポジトリを作るには、それなりの知識が必要です。ただし今なら第485回のaptlyで本格的なパッケージリポジトリを作るでも紹介したように、aptlyを使えば簡単にリポジトリを作ることが可能です。

しかしながら署名等も不要なローカルパッケージを提供するリポジトリで良ければ、Ubuntuには最初からインストールされているapt-ftparchiveとsources.listのfileスキームの組み合わせだけでも実現できます。

まず任意のディレクトリ、たとえば/srv/apt/repositotryにパッケージファイル一式をコピーしましょう。

$ sudo mkdir -p /srv/apt/repository/
$ sudo chown $USER: /srv/apt/repository/
$ cp *.deb /srv/apt/repository/

次にapt-ftparchiveでリポジトリのメタデータを作成します。

$ cd /srv/apt/repository/
$ apt-ftparchive packages . > Packages

これだけです。Packagesファイルの中には、個々のパッケージのメタデータとファイルパス、ハッシュ値が記載されていることを確認しましょう。ちなみにapt-ftparchive sources . > SourcesSourcesファイルを作れば、ソースパッケージリポジトリとしても運用可能です。

最後にこのディレクトリをリポジトリとして登録します。

$ echo "deb [trusted=yes] file:///srv/apt/repository/ ./" \
  | sudo tee /etc/apt/sources.list.d/local.list
$ sudo apt update

本記事をここまで読んでいるなら、上記の意味は簡単に理解できるはずです。fileスキームでリポジトリのURIを指定しています。メタデータは/srv/apt/repository/直下に保存しており、コンポーネントは用意していないことから、suite部分は単なるファイルパス./を記述しています。

また、リポジトリの署名検証はスキップし、全面的にこのローカルリポジトリを信頼させるために[trusted=yes]オプションを指定しておきました。

あとはapt policy FOOなどで、ローカルリポジトリのパッケージを参照できること、それがインストール対象に入っていることを確認しておきましょう。これでちょっとしたパッケージのインストール・テスト・アップグレードが簡単になります。

おすすめ記事

記事・ニュース一覧