Debian 系であえて古い APT パッケージをインストールする方法

たまに Debian や Ubuntu で、あえて古い APT パッケージをインストールしたくなる場合がある。

たとえば [Debian 系で unattended-upgrades を有効にする場合の追加設定 (メール通知, autoremove, autoclean, 再起動)](https://qiita.com/kitsuyui/items/11b4c0ebb9d1d2181853) で書いたような、自動アップデートがちゃんと設定できているか検証したい場合には、いちど過去の状態に戻して何度もリトライしたい、ということがある。他にも、いろいろな事情で古いパッケージを検証したくなることは、まれによくある。

以下、やり方を書いておく。 Ubuntu で実験したが、 Debian 系は共通の操作で良いはず。

# やり方

例として Ubuntu 16 で openssl の古いバージョンをインストールする場合を示す

## 1. まず戻すべきバージョンを知る

[apt-cache madison](https://manpages.debian.org/unstable/apt/apt-cache.8.en.html)
 を使う

```shell-session
$ apt-cache madison openssl
   openssl | 1.0.2g-1ubuntu4.8 | http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages
   openssl | 1.0.2g-1ubuntu4.6 | http://archive.ubuntu.com/ubuntu xenial-security/main amd64 Packages
   openssl | 1.0.2g-1ubuntu4 | http://archive.ubuntu.com/ubuntu xenial/main amd64 Packages
   openssl | 1.0.2g-1ubuntu4 | http://archive.ubuntu.com/ubuntu xenial/main Sources
   openssl | 1.0.2g-1ubuntu4.8 | http://archive.ubuntu.com/ubuntu xenial-updates/main Sources
   openssl | 1.0.2g-1ubuntu4.6 | http://archive.ubuntu.com/ubuntu xenial-security/main Sources
```

さらにこの表示されたバージョンにたいして `apt-cache show` や `apt-cache policy` を実行してみると詳細がわかる。

```shell-session
$ apt-cache show openssl=1.0.2g-1ubuntu4.6
Package: openssl
Architecture: amd64
Version: 1.0.2g-1ubuntu4.6
Priority: standard
Section: utils
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian OpenSSL Team <pkg-openssl-devel@lists.alioth.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 934
Depends: libc6 (>= 2.15), libssl1.0.0 (>= 1.0.2g)
Suggests: ca-certificates
Filename: pool/main/o/openssl/openssl_1.0.2g-1ubuntu4.6_amd64.deb
Size: 491668
MD5sum: 5a10ca1cfbd6ebad80264e2c2106c752
SHA1: 9ffe8c4291c09fd996a3afafdf85df8f5d9520ed
SHA256: 18f4d36f3e624be6ecfab385cd2e2fe4e5d7abc8030505dcacfa3ab243253cd1
Description: Secure Sockets Layer toolkit - cryptographic utility
Description-md5: 9b6de2bb6e1d9016aeb0f00bcf6617bd
Task: standard, ubuntu-core, ubuntu-core, mythbuntu-frontend, mythbuntu-backend-slave, mythbuntu-backend-master, ubuntu-touch-core, ubuntu-touch, ubuntu-sdk-libs-tools, ubuntu-sdk
Supported: 5y

```

さらに知りたい場合は [`https://launchpad.net/(distribution name)/+source/(package name)/(version)`](https://launchpad.net/ubuntu/+source/openssl/1.0.2g-1ubuntu4.6) のような URL を開いてみるのも良い。

## あとはいつもどおり apt-get install

OpenSSL を 1.0.2g-1ubuntu4.6 に戻してみよう

```shell-session
$ sudo apt-get install openssl=1.0.2g-1ubuntu4.6
```

できあがり！

## バージョンを固定したい場合

ついでに、このバージョンは再び apt-get upgrade すれば更新されてしまう。
通常は検証の一時的な設定のはずなのでそのような動作が望ましいが、これを固定したい場合もあるだろう。

`apt-mark hold` でバージョンを現在インストール済みのバージョンに固定することができる。

```shell-session
$ sudo apt-mark hold openssl
$ apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following packages have been kept back:
  openssl
.
.
.
```

## 固定を解消したい場合

`apt-mark unhold` を使う

```shell-session
$ sudo apt-mark unhold openssl
$ sudo apt-get upgrade
(もとどおり)
.
.
.
```

hold と unhold の他にも、手動でインストールしたパッケージを APT に認知してもらう場合にも `apt-mark manual` などで固定することはよくあるので覚えておくと良い。