Secure FreeBSD ports tree updating

Portsnap is a system for securely downloading and updating a compressed snapshot of the FreeBSD ports tree, and using this compressed snapshot to extract or update a (uncompressed) copy of the ports tree.

Historically, most people have used CVSup to keep their ports tree up to date, but CVSup has a number of limitations:

Portsnap avoids these problems by operating over HTTP (using FreeBSD's fetch(1) utility and a new experimental pipelined HTTP client), signing the snapshots using OpenSSL, and using more sophisticated delta compression to distribute the snapshots.

In order to compare the bandwidth usage of cvsup and portsnap for frequent updates of the FreeBSD ports tree, I used each method to update across a 58-hour period from 12:15 AM on January 13th, 2005 to 10:15 AM on January 15th, 2005. While cvsup used 6388kB of bandwidth (2418kB up, 3969kB down), portsnap only used 370kB (108kB up, 262kB down) -- an improvement of over a factor of 17. In addition, cvsup used 212 seconds of cpu time compared to portsnap's 32 seconds of cpu time -- a difference of over a factor of six -- and 534 seconds of wall-clock time compared to portsnap's 75 seconds of wall-clock time (but since the wall-clock time depends upon network congestion and server loads, it isn't particularly significant).

Portsnap stores a compressed snapshot of the ports tree (around 40 MB) on disk, by default in /usr/local/portsnap. This compressed snapshot can then be extracted as needed (eg, into /usr/ports).

Portsnap is in the FreeBSD base system for all versions from 5.5 upwards (including 6.0, which was released before 5.5); users of earlier FreeBSD releases can install portsnap from the ports tree (sysutils/portsnap).

I have a nice portsnap usage graph showing the number of systems running each version of portsnap (as approximated by the updates they fetch).

Usage

  1. Install sysutils/portsnap from the FreeBSD ports tree.
  2. To fetch a compressed snapshot, or update your current compressed snapshot, run `portsnap fetch`.
  3. To extract the ports tree, run `portsnap extract`.
  4. After extracting a ports tree, to update it to reflect changes in the compressed snapshot, run `portsnap update` -- this is much faster than `portsnap extract` because it avoids extracting directories which haven't changed.

Please note that when extracting a copy of the FreeBSD ports tree, portsnap will remove existing files. If you have any local changes (eg, extra patches which you've added into a port's files/ directory) then you'll have to put those back after updating the ports tree.

Please send any comments about this to me at "cperciva" at this domain.