LAN内に設置するAPTのPull through proxyでAPTパッケージの重複ダウンロードを回避

Posted by 雅楽斎 on Wednesday, August 7, 2019

TOC

パッケージのアップデートにかかる通信量を減らす

Linuxを含めてPCを使う際にパッケージのアップデートは必須になっていますが、同じ環境でのパッケージのアップデートの際に通信量を減らすことを考えます。今回はapt-cacher-ngを使用します。OpenJDKやLibreOffice等のサイズの大きいパッケージを複数の端末から更新する際に大きく威力を発揮します。

前提:通常時(未使用時)

sequenceDiagram Title: 通常のaptパッケージ更新 participant a as PC1 participant b as PC2 participant c as APTリポジトリ
(The Internet) a ->>+ a: apt-get update a ->> c: リポジトリ情報取得 c -->> a: リポジトリ情報 a ->>- a : リポジトリ情報更新 a ->>+ a: apt-get upgrade a ->> a: ローカルキャッシュ照合 alt ローカルキャッシュに
パッケージファイルがない a ->> c: 不足ファイルをダウンロード c -->>a: 不足ファイル end a ->>- a: パッケージインストール b ->>+ b: apt-get update b ->> c: リポジトリ情報取得 c -->> b: リポジトリ情報 b ->>- b : リポジトリ情報更新 b ->>+ b: apt-get upgrade b ->> b: ローカルキャッシュ照合 alt ローカルキャッシュに
パッケージファイルがない b ->> c: 不足ファイルをダウンロード c -->>b: 不足ファイル end b ->>- b: パッケージインストール

apt-cacher-ngの使用時

sequenceDiagram Title: apt-cacher-ngの導入時 participant a as PC1 participant b as PC2 participant c as apt-cacher-ng
(in LAN) participant d as APTリポジトリ
(The Internet) Note left of c: 待ち受けポートは
TCP/3142 a ->>+ a: apt-get update a ->> c: リポジトリ情報取得 c ->> d: リポジトリ情報取得 d -->> c: リポジトリ情報 c ->> c: リポジトリ情報更新 c -->> a: リポジトリ情報 a ->>- a : リポジトリ情報更新 a ->>+ a: apt-get upgrade a ->> a: ローカルキャッシュ照合 alt ローカルキャッシュに
パッケージファイルがない a ->> c: 不足ファイルをダウンロード alt ローカルキャッシュに
パッケージファイルがない c ->> d: 不足ファイルをダウンロード d -->>c: 不足ファイル end c -->>a: 不足ファイル end a ->>- a: パッケージインストール b ->>+ b: apt-get update b ->> c: リポジトリ情報取得 c ->> d: リポジトリ情報取得 d -->> c: リポジトリ情報 c ->> c: リポジトリ情報更新 c -->> b: リポジトリ情報 b ->>- b : キャッシュ情報更新 b ->>+ b: apt-get upgrade b ->> b: ローカルキャッシュ照合 alt ローカルキャッシュに
パッケージファイルがない b ->> c: 不足ファイルをダウンロード Note Right of c: PC1の時に取得して
いるパッケージが
あるので、ここでの
インターネット接続は
発生しない c -->>b: 不足ファイル end b ->>- b: パッケージインストール

apt-cacher-ngがダウンロードしたパッケージが合致する条件

apt-cacher-ngがダウンロードしたキャッシュを再利用する条件は同じURLの指すdebパッケージである必要がある為、各PCで以下の場合にインターネットへの接続を減らすことができます。

  • 同じapt-lineであること
  • 同じリリースバージョンであること1
  • アーキテクチャ非依存のパッケージ(hogehoge.all.deb)である、又は各PCのアーキテクチャ(i386/amd64/armhf/arm64)が同じであること

apt-cacher-ngを使用する

apt-cacher-ngはC++で実装されるソフトウェアで、マルチプラットフォームで動作します。ライセンスはオリジナルBSDライセンス/The BSD 4-Clause Licenseです。Debian(Buster)での動作プラットフォームはamd64/arm64/armel/armhf/i386/mips/mips64el/mipsel/ppc64el/s390x、Ubuntu(18.04)での動作プラットフォームはamd64/arm64/armhf/i386/ppc64el/s390xとなっています。今回はRaspberry Pi2(Ubuntu 18.04 armhf)へインストールします。

サーバーへのインストール

# apt-get install apt-cacher-ng

設定ファイル(/etc/apt-cacher-ng/acng.conf)の変更

サーバー側で変更が必要なものを記載します。ファイルの書き換え後は以下のコマンドでdaemonの再起動が必要です。

# systemctl restart apt-cacher-ng

キャッシュディレクトリの変更

Raspberry Piで運用する場合にSDをキャッシュディレクトリに指定するのは割と自殺行為なので、SSDに変更します。

CacheDir: /mnt/ssd/ippan/apt-cacher-ng

また、キャッシュディレクトリの作成とオーナー・グループの変更を行います。

# mkdir /mnt/ssd/ippan/apt-cacher-ng
# chown apt-cacher-ng:apt-cacher-ng /mnt/ssd/ippan/apt-cacher-ng/

remap

apt-cacher-ngはTLS(https)接続ができないので、TLS接続の必要なリポジトリを追加した場合は以下どちらかの対応が必要です。

  • TLS接続をクライアントからリポジトリに直接させるようにするかわりに、パッケージをキャッシュしない
  • パッケージをキャッシュさせるため、remapする。この場合は、クライアント側のaptリポジトリのURLも書き換える

まず後者で設定します。接続クライアント側のURLも書き換えないといけないというかなり大きなデメリットがあるんですが、プロキシにキャッシュする方がメリットが大きいと判断しました。

remapするリポジトリをどう書き換えるのか

https:// で始まるURLをhttp:// で始まるURLに置換するようにremapすると何故かパッケージをダウンロードしてキャッシュもするようになります。現在手元で置換しているドメインは下表の通り。

元のURLremapとして記述するURL
https://download.docker.comhttp://download.docker.com
https://apt.syncthing.nethttp://apt.syncthing.net
https://deb.etcher.iohttp://deb.etcher.io 2
https://typora.iohttp://typora.io
https://download.mono-project.comhttp://download.mono-project.com
https://mkvtoolnix.downloadhttp://mkvtoolnix.download

/etc/apt-cacher-ng/acng.confに以下を追記します。

Remap-docker:    http://download.docker.com ; https://download.docker.com
Remap-syncthing:    http://apt.syncthing.net ; https://apt.syncthing.net
Remap-typora:    http://typora.io ; https://typora.io
Remap-mono:    http://download.mono-project.com ; https://download.mono-project.com
Remap-mkvtoolnix:    http://mkvtoolnix.download ; https://mkvtoolnix.download

置換後のURLは存在しないドメインにすると接続しに行ってエラーになってしまうので、httpsをhttpに変更しただけにしています。

Remap-に続く文字列は任意ですが、キャッシュディレクトリに作られるディレクトリ名になるので、わかりやすい文字列にするのが良いでしょう。

remapで対応できないリポジトリをキャッシュさせずに通過させる

前項に書いた様に、tls接続が必要なリポジトリではremapするかキャッシュを諦めて通過させるかどちらかをすることで運用ができます。ここではキャッシュを諦めて通過させる方法を記載します。

apt-cacher-ngサーバーの設定ファイル (/etc/apt-cacher-ng/acng.conf)にリポジトリに対応するよう以下を記載します。クライアント側では対応は必要ありません。3

PassThroughPattern: ^((deb\.etcher\.io)|(dl\.bintray\.com)):443$

daemon起動設定

パッケージとしてインストールした場合はsystemdのdaemonとして登録されているので、自動起動になっている事を確認して再起動します。

# systemctl is-enabled apt-cacher-ng
enabled
# systemctl restart apt-cacher-ng

クライアントの設定変更

(apt-cacher-ngを動かす端末含めて)接続するクライアントは以下の変更をします。

/etc/apt/apt.conf.d/02cacher-ngを作成

/etc/apt/apt.conf.d/の下に現在あるファイル名と重複しないようにファイルを作成し、以下の内容を記載します。192.168.1.129はapt-cacher-ngを動作させている端末のIPアドレスです。

Acquire::http::Proxy "http://192.168.1.129:3142/";

また、apt-cacher-ngを動作させる端末の場合はループバックアドレスで良いでしょう。

Acquire::http::Proxy "http://127.0.0.1:3142/";

httpsリポジトリのapt-lineを書き換え

httpsのaptリポジトリがある場合は/etc/apt/sources.list等を書き換えます。書き換えはサーバー側のremapに合わせます。

エラーが発生する場合

apt-cacher-ngは通信量の削減に役立つ4のですが、現在Ubuntu 18.04LTSでインストール可能な3.1.1build1では通信時にエラーが発生していた場合でも正常処理として流してしまい、proxyとして利用している端末からは同じエラーが出続けるようです。

特定のリポジトリにエラーがある

# apt-get update
Hit:1 http://jp.archive.ubuntu.com/ports bionic InRelease
Hit:2 http://ppa.launchpad.net/ubuntu-raspi2/ppa/ubuntu bionic InRelease
Get:3 http://jp.archive.ubuntu.com/ports bionic-security InRelease [88.7 kB]
Hit:4 http://download.docker.com/linux/ubuntu bionic InRelease
Err:3 http://jp.archive.ubuntu.com/ports bionic-security InRelease
  Splitting up /var/lib/apt/lists/partial/jp.archive.ubuntu.com_ports_dists_bionic-security_InRelease into data and signature failed
Get:5 http://jp.archive.ubuntu.com/ports bionic-updates InRelease [88.7 kB]
Get:6 http://jp.archive.ubuntu.com/ports bionic-backports InRelease [74.6 kB]
Fetched 252 kB in 1min 24s (3000 B/s)
Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://jp.archive.ubuntu.com/ports bionic-security InRelease: Splitting up /var/lib/apt/lists/partial/jp.archive.ubuntu.com_ports_dists_bionic-security_InRelease into data and signature failed
W: Failed to fetch http://jp.archive.ubuntu.com/ports/dists/bionic-security/InRelease  Splitting up /var/lib/apt/lists/partial/jp.archive.ubuntu.com_ports_dists_bionic-security_InRelease into data and signature failed
W: Some index files failed to download. They have been ignored, or old ones used instead.

これらの症状が出ている場合、本当にリポジトリにエラーがある場合はあまりなく、apt-cacher-ngのキャッシュが壊れている場合があります。その場合、apt-cacher-ngを使用していない別の端末から同じapt-lineにapt-get updateを実行しても、該当のエラーは発生しません。

apt-cacher-ng側でなんとかして直す方法を考えます。apt-cacher-ngのキャッシュディレクトリの構成は大まかに以下の様になっています。

ドメイン名orRemap名/
└── サブディレクトリ(ない場合あり)
    ├── dists
    │   └── リリース名
    │       ├── 各種control情報
    │       └── 各種control情報.head
    └── pool
        └── カテゴリ名
            └── パッケージ名頭文字(例外あり)
                ├── hogehoge.deb
                └── hogehoge.deb.head

ここで、.headというファイルはそのファイルのメタ情報(取得日時、サイズ等)が記載されるファイルです。

該当するファイルがない場合は実行時に取得しに行くので、apt-cacher-ngを実行しているサーバーの対象ディレクトリに入って、おかしくなっているファイルを削除します。今回は「Err:3 http://jp.archive.ubuntu.com/ports bionic-security InRelease」に該当するcontrol情報を削除します。

$ sudo rm -rf jp.archive.ubuntu.com/ports/dists/bionic-security/*

また、特定のパッケージだけがダウンロードに失敗してファイルが壊れていると思われる場合はpoolの下のパッケージファイル(debとdeb.head)を削除するとaptコマンドを実行できるようになります。


  1. 但し、リリースバージョンが変わっても更新されないパッケージの場合は同じURLになります。 [return]
  2. Etcherはapt-lineが【 https://deb.etcher.io 】になっていますが、これのリダイレクト先がドメインの変更だけでなく【 https://dl.bintray.com/etcher/debian 】になっているため、remapでの変更で動作確認ができていません。 [return]
  3. 現状、etcherのみ記載しています。 [return]
  4. 複数台で同じapt-line、アーキテクチャの参照をしている場合に限りますが [return]

comments powered by Disqus