第5章 パッケージ管理の応用(dpkg/apt・rpm/dnf)
LPIC-1 102.3〜102.5 相当
初級の第9章では apt / dnf / pacman の基本操作を扱いました。ここでは、パッケージ管理の内部の仕組みにもう一歩踏み込みます。
dpkg — Debian系パッケージの低レベル操作
apt は依存関係を自動解決してくれる高レベルなツールですが、その内部では dpkg がパッケージファイル(.deb)そのものを扱っています。
$ sudo dpkg -i package.deb # .debファイルを直接インストール
Selecting previously unselected package myapp.
Unpacking myapp (1.2.0-1) ...
Setting up myapp (1.2.0-1) ...
$ dpkg -l # インストール済みパッケージ一覧
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
||/ Name Version Architecture Description
+++-==============-===============-============-=================
ii nginx 1.24.0-2ubuntu7 amd64 small, powerful, scalable web...
ii openssh-server 1:9.6p1-3ubuntu13 amd64 secure shell server
...(この後もインストール済みパッケージが続く)
$ dpkg -L nginx # nginxが持つファイル一覧
/etc/nginx
/etc/nginx/nginx.conf
/usr/sbin/nginx
/var/log/nginx
...(この後も所属ファイルが続く)
$ sudo dpkg -r nginx # 削除(設定ファイルは残る)
(Reading database ... 184291 files and directories currently installed.)
Removing nginx (1.24.0-2ubuntu7) ...
この行のこの値に注目: dpkg -lの各行先頭にあるiiは「Installed(インストール済み・設定完了)」を示す状態コードで、rc(削除済みだが設定ファイルが残っている)などとの違いを見分けられます。dpkg -Lはパッケージ名から所属ファイルを調べる向きで、逆にファイルパスからパッケージ名を調べたいときは後述のdpkg -Sを使います。
rpm — Red Hat系パッケージの低レベル操作
$ sudo rpm -ivh package.rpm # インストール(-i: install, -v: verbose, -h: 進捗表示)
Verifying... ################################# [100%]
Preparing... ################################# [100%]
Updating / installing...
1:myapp-1.2.0-1.el9 ################################# [100%]
$ rpm -qa # インストール済みパッケージ一覧
httpd-2.4.57-5.el9_4.x86_64
openssh-server-8.7p1-38.el9.x86_64
...(この後もインストール済みパッケージが続く)
$ rpm -ql httpd # httpdが持つファイル一覧
/etc/httpd/conf/httpd.conf
/usr/sbin/httpd
/var/log/httpd
...(この後も所属ファイルが続く)
$ sudo rpm -e httpd # 削除(erase)
(正常に削除できた場合、rpm -eは既定では何も表示しない)
この行のこの値に注目: rpm -ivhの[100%]という進捗バーが最後まで到達し、エラー行が出ていなければインストール成功です。rpm -qaの各行はパッケージ名-バージョン-リリース.アーキテクチャという形式になっており、dpkgの表形式とは表示のされ方が異なる点に注意してください。
高レベルツールと低レベルツールの対応
| 操作 | Debian系(低レベル/高レベル) | Red Hat系(低レベル/高レベル) |
|---|---|---|
| ファイルからインストール | dpkg -i | rpm -ivh |
| 依存関係解決込みでインストール | apt install | dnf install |
| 一覧表示 | dpkg -l | rpm -qa |
| 検索 | apt search | dnf search |
共有ライブラリの確認
多くのプログラムは、共通の機能を「共有ライブラリ」として外部化しています。実行に必要なライブラリが見つからないと、プログラムは起動できません。
$ ldd /usr/bin/nginx # 実行ファイルが依存する共有ライブラリを確認
linux-vdso.so.1 (0x00007ffcabf12000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f2a1c000000)
libssl.so.3 => /lib/x86_64-linux-gnu/libssl.so.3 (0x00007f2a1bf00000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2a1bd00000)
$ sudo ldconfig # 共有ライブラリのキャッシュを更新
(正常に完了した場合は何も表示しない)
この行のこの値に注目: lddの出力で、探しているライブラリの右側に実際のパス(=> /lib/...)が表示されていれば正しく解決できています。もしここがnot foundになっている場合、そのライブラリが未インストールか、後述のldconfigによるキャッシュ更新が必要な状態です。
リポジトリの設定
apt や dnf は、あらかじめ設定された「リポジトリ」と呼ばれるサーバーからパッケージ情報を取得します。
| ディストリ系統 | リポジトリ設定ファイル |
|---|---|
| Debian系 | /etc/apt/sources.list、/etc/apt/sources.list.d/*.list |
| Red Hat系 | /etc/yum.repos.d/*.repo |
$ sudo apt update # リポジトリの最新パッケージ一覧を取得
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Reading package lists... Done
$ apt-cache policy nginx # インストール候補のバージョンと取得元を確認
nginx:
Installed: 1.24.0-2ubuntu7.4
Candidate: 1.24.0-2ubuntu7.4
Version table:
*** 1.24.0-2ubuntu7.4 500
500 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages
$ sudo dnf repolist # 有効なリポジトリの一覧(Red Hat系)
repo id repo name
appstream Rocky Linux 9 - AppStream
baseos Rocky Linux 9 - BaseOS
extras Rocky Linux 9 - Extras
この行のこの値に注目: apt-cache policyのInstalled行とCandidate行が一致していれば、そのパッケージは最新の候補バージョンがすでに入っている状態です。両者が異なる場合は、apt upgradeで更新できる新しいバージョンが存在することを意味します。
依存関係の問題と検証
手動でdpkg/rpmを操作したり、インストールが途中で失敗したりすると、依存関係が壊れた状態になることがあります。
$ sudo apt --fix-broken install # 壊れた依存関係を解決
Reading package lists... Done
Building dependency tree... Done
Correcting dependencies... Done
The following packages will be upgraded:
libssl3
1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
$ rpm -Va # インストール済みパッケージのファイルを検証(改変・欠落を検出)
S.5....T. c /etc/nginx/nginx.conf
missing /etc/nginx/conf.d/old.conf
$ rpm -qf /etc/nginx/nginx.conf # 特定のファイルがどのパッケージに属するか調べる(-qfはquery fileの意味)
nginx-1:1.20.1-14.el9.x86_64
$ dpkg -S /etc/nginx/nginx.conf # 同様の操作をDebian系で行う場合
nginx-common: /etc/nginx/nginx.conf
この行のこの値に注目: rpm -Vaの行頭記号は変更点の種類を表し、Sはファイルサイズが変わった、5はMD5チェックサムが変わった、Tはタイムスタンプが変わったことを意味します(.は変更なし)。missingは本来あるはずのファイルが存在しないことを示し、設定ファイルの改変や欠落を調査する手がかりになります。
rpm -qf / dpkg -S)と、「パッケージが持つファイル一覧を調べる」操作(rpm -ql / dpkg -L)は向きが逆であることを混同しないようにしましょう。
特定パッケージのバージョンを固定する
運用中のシステムでは、動作確認済みのバージョンから意図せず更新されてしまうと困る場合があります。そのようなときは、パッケージを「更新対象から除外(保留)」する機能を使います。
$ sudo apt-mark hold nginx # nginxを更新対象から除外(Debian系)
nginx set on hold.
$ apt-mark showhold # 保留中のパッケージ一覧を確認
nginx
$ sudo apt-mark unhold nginx # 保留を解除
Canceled hold on nginx.
$ sudo dnf install python3-dnf-plugin-versionlock # Red Hat系では versionlock プラグインで同様のことを行う
...(インストール処理。完了時は Complete! と表示される)
$ sudo dnf versionlock add nginx
Adding versionlock on: nginx-1:1.20.1-14.el9.*
この行のこの値に注目: apt-mark hold実行直後にnginx set on hold.という確認メッセージが返り、apt-mark showholdで一覧に含まれていれば保留設定が有効です。この状態ではapt upgradeを実行してもnginxだけは対象から除外されます。
パッケージの署名検証
信頼できないパッケージを誤ってインストールしてしまわないよう、多くのディストリビューションでは配布パッケージにGPG署名を付け、リポジトリ設定に登録された公開鍵で検証してからインストールする仕組みが標準で有効になっています。
$ sudo apt-key list # 登録済みの信頼済み鍵を確認(新しめのDebian系では非推奨、代わりに/etc/apt/trusted.gpg.d/を使う)
/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg
------------------------------------------------------
pub rsa4096 2018-09-17 [SC]
F6EC B376 2474 EDA9 D21B 7022 8719 20D1 991B C93C
uid [ unknown] Ubuntu Archive Automatic Signing Key (2018) <ftpmaster@ubuntu.com>
$ sudo rpm --import RPM-GPG-KEY-example # Red Hat系で公開鍵を手動でインポート
(正常にインポートできた場合は何も表示しない)
$ rpm -K package.rpm # 個別のrpmファイルの署名を検証
package.rpm: digests signatures OK
この行のこの値に注目: rpm -Kの結果がdigests signatures OKであれば、ファイルの改ざんがなく、登録済みの鍵で正しく署名されていることが確認できています。ここがNOT OKやMISSING KEYSと表示された場合は、出所不明なパッケージである可能性があるため、インストールを見送るべきです。
キャッシュのクリーンアップ
apt・dnfはダウンロードしたパッケージファイルをローカルにキャッシュするため、長く使っているとディスクを圧迫することがあります。
| 操作 | Debian系 | Red Hat系 |
|---|---|---|
| キャッシュのクリア | sudo apt clean | sudo dnf clean all |
| 使われなくなった依存パッケージの削除 | sudo apt autoremove | sudo dnf autoremove |
豆知識: パッケージ形式の変換
alienというツールを使うと、.rpmファイルを.debに変換する(あるいはその逆)といったことも可能です。ただし依存関係やパッケージ内のスクリプトの互換性までは保証されないため、あくまで応急的な手段として扱われます。可能な限り、そのディストリビューション向けに公式に配布されているパッケージを使うのが安全です。
依存関係グラフをたどる:なぜ「消したいだけなのに大量に消えそうになる」のか
あるパッケージをremoveしようとすると、「これに依存している他のパッケージも一緒に削除されます」という警告が表示され、想定より遥かに多いパッケージ名がずらりと並ぶことがあります。これは、パッケージ管理システムが依存関係を双方向に把握しているために起きる現象です。たとえば汎用的なライブラリパッケージを削除しようとすると、それに依存しているアプリケーションもまとめて削除候補に挙がってしまいます。このような警告が出たときは、慌ててyを押さず、削除候補の一覧を落ち着いて確認する習慣をつけましょう。本当に消したいのがライブラリ側なのか、それとも動作確認のために入れた別のパッケージが原因で依存関係が複雑化しているだけなのかを見極めることが重要です。
パッケージのダウングレード
アップデート後にソフトウェアの挙動がおかしくなった場合、原因が更新にあると判断できれば、以前のバージョンに戻す(ダウングレードする)ことも選択肢になります。apt環境ではキャッシュに残っている過去バージョンの.debファイルからdpkg -iで戻す方法や、リポジトリで公開されているバージョンを明示的に指定してインストールし直す方法があります。ただしダウングレードは他のパッケージとの依存関係の整合性を崩すリスクがあるため、まずは可能であれば動作確認用の別環境で試してから本番に適用するのが安全です。