第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
「suite
」と「component
」はリポジトリ固有の設定です。
「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
ファイルないしRelease
とRelease.gpg
ファイルを所得するのです。
「suite
」はファイルパスを直接指定することもあります。これはInRelease
やPackages
といったメタデータが同じディレクトリに存在する場合に有効です。なおファイルパスを指定する場合は、「 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-tor 、in-toto という仕組みでパッケージを取得できるapt-transport-in-toto ぐらいです。
URIにはミラーリポジトリを指定できます。たとえばUbuntuの公式リポジトリは「archive.ubuntu.com」ですが、日本の公式ミラーサーバーとして「jp.archive.ubuntu.com」も利用可能です[2] 。
[2] このミラーリポジトリは富山大学の協力のもと、複数台のサーバーをUbuntu Japanese Teamが管理・運用しています。実質的には、Ubuntu Weekly Topics でおなじみの吉田さんが担当しているため、お世話になっている人はたまに感謝の言葉を表明してもバチはあたらないでしょう。また上記以外にも日本のミラーはいくつも存在するため、ミラーサーバーのリスト を参考に、普段使うミラーサーバーを直接指定する方法もあります。ただしいずれのサーバーも管理者の技術的・政治的な涙ぐましい努力によって維持されています。常識を超えた無茶なアクセスは禁物です。
ちなみに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] 。
[4] manページにもあるように、将来的に1行フォーマットを非推奨にして、deb822に移行する目論見ではあるようですが、何か具体的に決まっているわけではありません。現時点では利用者レベルだと「こういうフォーマットがある」程度の認識で十分でしょう。リポジトリを操作するツール等を開発している場合は、気にしておいたほうがいいかもしれません。
ローカルリポジトリの作り方
真っ当な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 . > Sources
」でSources
ファイルを作れば、ソースパッケージリポジトリとしても運用可能です。
最後にこのディレクトリをリポジトリとして登録します。
$ 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
」などで、ローカルリポジトリのパッケージを参照できること、それがインストール対象に入っていることを確認しておきましょう。これでちょっとしたパッケージのインストール・テスト・アップグレードが簡単になります。