FrontPage  Index  Search  Changes  RSS  wikifarm  Login

portsnap

はじめに

portsnap とは

portsnap は secure に FreeBSD の ports ツリーを更新することができるツールです。作者は FreeBSD Security Officer Team の一人である Colin Percival 氏で、氏の尽力もあって portsnap は FreeBSD 6 からは標準ツールとして base system にも取り込まれました。

CVSup と何が違うの?

Colin Percival 氏は従来の CVSup に関して以下のように述べています*1

  1. CVSup は安全じゃない。プロトコルで暗号化も電子署名も使っていないし、通信を邪魔できる攻撃者であれば更新しているツリーに任意のデータを挿入できてしまう。
  2. CVSup は エンド−エンド じゃない。上記に関連して、これは CVSup ミラーを汚染できれば、そのミラーを利用しているユーザに任意のデータ供給が可能であることを意味する。
  3. CVSup は小さな更新を頻繁にするようには設計されていない。CVSup は CVS ツリーの配布には非常に良く、大きな変更がなされたツリー(例えば 1ヶ月以上の間があいた際のツリー)を更新するには非常に効率的である一方、わずかなファイルしか変更されていない場合でもツリーの全てのファイルのリストを送信するため、極めて非効率である。
  4. CVSup は独自のプロトコルを使用している。これはファイアウォールの背後に居るユーザには問題(外部の 5999/tcp への接続許可が必要)であるし、非常に重いサーバ(cvsupd)が必要となる。

これに対する解として portsnap が誕生しました。portsnap には以下のような特徴があります*2

  • プロトコルには HTTP を使用する
  • スナップショットには OpenSSL を用いて電子書名を行う
  • スナップショットの配布のために、より洗練されたデルタ圧縮(Binary diff)を使用する

これにより、ファイアウォール下で CVSup ができないマシンなどでも HTTP による ports ツリーの更新が可能となるだけでなく、取得したファイルの安全性の確認が可能となること、また ports ツリーを圧縮した状態で転送するためにバイナリ差分が利用されるために(CVSup と比較して)短時間かつ低負荷での更新が可能となります。

ちなみに

  • INDEX/INDEX-5/INDEX-6 ファイルを提供する

というのもポイントかもしれません。'make fetchindex' や 'portsdb -F' による INDEX/INDEX-5/INDEX-6 ファイルの取得も不要になりますね。

便利なの?

便利です :-)。以下の内容に頷ける方なら多分便利さを実感していただけると思います。

  • ports ツリーを最新(-current)にしたいだけで、local patch などは維持する必要が無い
  • cvsup-mirror(net/cvsup-mirror) で CVSup ツリーをローカルにミラーして管理下のサーバはそれを参照しているが、ミラーサーバの負荷が気になる
  • ポリシー上、外部サイトへの 5999/tcp を開けることができないが、80/tcp なら(プロキシ経由などで)大丈夫

インストールと設定

FreeBSD 6 からは標準ツールになりましたので、FreeBSD 6 以降を使用している方はインストール作業が不要です。FreeBSD 4, 5 を使用している方は以下の手順に従ってください。

インストール

インストールは ports を用いて行います。なお、以下のパッケージに依存していますので、未だインストールされていない場合は同時にインストールされます。

  • bsdiff(misc/bsdiff)
  • freebsd-sha256(sysutils/freebsd-sha256)*3

では実際にインストールしてみましょう。以下のどちらかの方法が使えます。

portinstall を使う

portupgrade(sysutils/portupgrade) を使用している場合は portinstall が楽ですね。

# portinstall portsnap

普通に make する

portsnapsysutils/portsnap にありますので、以下のようになります。

# cd /usr/ports/sysutils/portsnap
# make install clean

設定

portsnap の設定ファイル(のサンプル)は以下にあります。

ports からインストールした場合(ports 版)
/usr/local/etc/portsnap.conf.sample
FreeBSD 6 以降の場合(base system 版)
/etc/portsnap.conf

ports からインストールした場合は portsnap.conf.sampleportsnap.conf に copy すれば良いでしょう。

# cd /usr/local/etc
# cp portsnap.conf.sample portsnap.conf

除外するカテゴリ

バージョン 1.0 から*4 細かい設定ができるようになりました。詳細は man portsnap.conf ですが、チョッとだけ紹介します。

portsnap.conf を見ると

# REFUSE arabic chinese french german hebrew hungarian japanese
# REFUSE korean polish portuguese russian ukrainian vietnamese

というコメント行がありますが、REFUSE キーワードの後に更新しないカテゴリを指定することができるようになったようですね。CVSup より十分高速な気がする portsnap ですが、更に高速に... とか、不要なカテゴリでディスクを消費したくない方は設定してみてください。

使ってみる

初めて使う場合

portsnap を初めて使う場合は以下の点に注意して下さい。

  • 今まで CVSup を使っていたりして /usr/ports/ ディレクトリ以下にファイルが存在する場合、それらは一旦削除されます。ローカルで独自の ports skelton や patch を維持している場合は、それらを一旦退避させておく必要があります
  • portsnap は最初だけ全ての ports ツリー全体を portsnap.conf ファイルで指定したサイト(デフォルトでは www.daemonology.net)から取得し、ディスク上に展開します。ある程度の時間とマシン・回線リソースを消費しますので、マシンが忙しくないときに実施した方が良いでしょう。

では実際に使ってみます。以下のコマンドを実行して下さい。

# portsnap fetch && portsnap extract && portsnap update

portsnap のサイトから ports ツリーの最新アーカイブを取得し、それをディスク上に展開していく過程が以下のように表示されると思います。

  • fetch
Fetching snapshot tag... done.
Fetching snapshot metadata... done.
Updating from Tue May 17 01:28:57 JST 2005 to Tue May 17 13:36:36 JST 2005.
Fetching 4 metadata patches... done.
Applying metadata patches... done.
Fetching 0 metadata files... done.
Fetching 80 patches.....10....20....30....40....50....60....70....80 done.
Applying patches... done.
Fetching 9 new ports or files... done.
  • update
Removing old files and directories... done.
Extracting new files:
/usr/ports/MOVED
/usr/ports/Mk/bsd.gnome.mk
/usr/ports/audio/Makefile
(途中省略)
/usr/ports/x11-toolkits/gtk12/
/usr/ports/x11-toolkits/gtkmathview/
/usr/ports/x11-toolkits/libxfce4gui/
/usr/ports/x11-wm/xfce4-panel/
Building new INDEX files... done.

これが終わったら

# portversion -vL=

などを行い、更新された ports/packages の一覧を得ることができます。

なお、もし以下のようなエラーメッセージが出たら portsnap.conf ファイルのパスを確認して下さい*5

portsnap: URL must be given via command line or configuration file.

手動で ports ツリーを更新(2回目以降)

2回目以降の更新は一手間減ります。

# portsnap fetch && portsnap update

この後、portversion などでパッケージの更新情報を取得すれば良いでしょう。

cron で最新の ports ツリーデータを取得

portsnap には cron によって実行されるモードも準備されています。以下の内容を root の crontab に登録しましょう*6

0 3 * * * /usr/local/sbin/portsnap cron

あるいは /etc/crontab に以下のように記載しても良いでしょう*7

0 3 * * * root /usr/local/sbin/portsnap cron

こうすると毎日午前 3:00 に portsnap が起動され、最新の port ツリーを取得することができます。ただし手動で実施する場合と異なる点があります。

  • 起動は午前 3:00 ですが、実際に fetch するのは何秒(or 何分)か後になります。これは portsnap サイトへのアクセスが殺到するのを防ぐためとのことです。
  • オプション cron はオプション fetch と同じです。取得したファイルを展開するには別途オプション update を付けて portsnap を実行する必要があります。
  • 『午前 3:00』というのは適当に書いたのではなく、portsnap のマニュアルに指示があるので極力変えないで下さい。ただしマシンの時間が UTC の場合は『午前 3:00』以外 にするように とのことです。

ports ツリーの自動更新 & 更新パッケージの通知

便利な portsnap ですが、毎回 fetch && update したり、portversion で更新された ports/packages を調べるのは面倒なので、fetch & update & 更新パッケージの通知を行う shell script を作って自動化してみましょう。

shell script の作成・保存

例えば 499.status-pkgupdate のような内容のファイルを作成し、/usr/local/etc/periodic/daily/ ディレクトリ*8 に適当な名称で保存します。実行権限(755 or 711)をつけるのも忘れないで下さい

これで次回の daily run output(毎日システムから来るメール)に以下のような行が出現することがあります*9ので、この情報に基づいて ports/packages を portupgrade にて更新すると良いでしょう。

Ports/packages update check:
gettext-0.14.1              <  needs updating (port has 0.14.4)
qmail-1.03_3                <  needs updating (port has 1.03_4)

更新履歴

ver. 0.9.3 対応(2005/7/31)
portsnap のバージョン 0.9.3 から fetch の際に -x オプションが利用できるようになりました。ここ にあるように未だ実験的なコードだそうですが fetch 時の速度が最大 3〜10倍(!)早くなるそうです。上記文章も -x オプションを使用するように修正しました。なお shell script は未修正です。明日以降に更新しますのでご了承を... shell script も修正しました('05/8/2)。
ver. 0.9.5 リリース(2005/9/18)
気づいたのが 9/18 というだけですが、0.9.5 がリリースされています。0.9.4 で make_index が coredump する問題が修正されているようです。
base system 版の記述を追加(2005/12/31)
ports 版とは設定ファイルのパスやコマンドラインオプション(-x)が異なるので少し書いてみました。
REFUSE キーワードの記述を追加(2006/2/12)
バージョン 1.0 が出た際に portsnap.conf の内容が刷新されましたので、その中でも目玉(?)な REFUSE キーワードを追記しました。
-x オプション の記述を削除(2006/02/24)
バージョン 1.0 が出た際に -x オプションが廃止されたようです。廃止というかデフォルトの挙動になったみたいです。スクリプトも修正しておきました。
499.status-pkgupdate を更新(2006/07/24)
http://d.hatena.ne.jp/cocelo/20060713/1152782079 で Cocelo さんが base system の portsnap を使えない点を指摘されていたので、対応してみました。

コメント

  • 2005-07-07 (木) 10:40:28 にしおか : 499.status-pkgupdateの21行目ですが、(portsnap fetch && portsnap update) >/dev/null 2>&1 ではないでしょうか?
  • 2005-07-12 (火) 22:24:53 BSDmad : cron -> fetch という意味でしょうか? これは cron で正しいです。cron にすることで portsnap サイトへのアクセスをランダムに遅延することができるからです。マニュアルにも cron から使うときは "cron" を使うように書いてありますので...
  • 2005-08-01 (月) 11:18:31 BSDmad : 0.9.3 -> 0.9.4 だそうです。0.9.3 な人で -x を設定した人は早々に update を...
  • 2005-08-01 (月) 20:31:16 tkb : ちょっと試した限りでは、特定のカテゴリを取得しないってことは出来ないっぽいですね。デメリットかも。公式サイトにはbase systemにインポートするって書いてあるし、こっちが主流になっていくのかなぁ。
  • 2005-08-02 (火) 09:43:30 BSDmad : ports ツリーをアーカイブした上で、そのバイナリ差分を転送してるみたいですね。カテゴリ単位で... というのは標準では難しそうですが、自前で portsnap サーバを作るという選択肢は有りそうです :-)。
  • 2005-09-18 (日) 10:08:23 BSDmad : まだ 6 or 7 の環境を持っていないのですが、そろそろどっかに環境が要りそうですね...
  • 2005-10-24 (月) 09:36:26 名無しさん : Proxy経由なのですが、何度やっても fetch: transfer timed out になるのは、何故?
  • 2005-12-31 (土) 21:28:03 BSDmad : Proxy 経由はちょっと分かりません。ごめんなさい...
  • 2006-01-15 (日) 22:07:43 名無しさん : Proxyを経由する際には、環境変数の設定が必要ですよ。HTTP_PROXYとか。
  • 2006-02-12 (日) 12:45:34 BSDmad : 06/1/30 にバージョン 1.0 が出てますね。0.9.x を使っていた人は portsnap.conf の内容が変わっているそうなのでご注意ください。
  • 2006-05-22 (月) 09:05:58 BSDmad : コメントスパムがひどいので、一時コメント機能を停止します。
Last modified:2006/07/24 10:23:28
Keyword(s):
References:[SideMenu] [csup]

*1 もちろん意訳ですので、原文 もご覧下さい。

*2 これまた意訳ですので、原文 もご覧下さい。

*3 FreeBSD 6-current だと不要なようです

*4 base system 版も、です

*5 ports 版の場合は多分 portsnap.conf.sample の copy 忘れです :p)

*6 root で crontab -e して下さい。

*7 この辺は各サイトのポリシーに併せて適宜選択して下さい。

*8 ディレクトリが無ければあらかじめ作って下さいね。

*9 何も更新される ports/packages が無いこともありますから。