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:
- CVSup is insecure. The protocol uses no encryption or signing, and any attacker who can intercept the connection can insert arbitrary data into the tree you are updating.
- CVSup isn't end-to-end. Related to the previous point, this means that anyone who can compromise a CVSup mirror can feed arbitrary data to the people who are using that mirror.
- CVSup isn't designed for frequent small updates. While CVSup is very good at distributing CVS trees, and is very efficient for updating a tree which has been significantly changed (eg, by a month or more of commits), it transmits a list of all the files in the tree, which makes it quite inefficient if only a few files have changed.
- CVSup uses a custom protocol. This can cause problems for people behind firewalls -- outgoing connections on port 5999 need to be permitted -- and it needs a heavyweight server (cvsupd).
Portsnap avoids these problems by operating over HTTP, signing the snapshots, and using more sophisticated delta compression to distribute the snapshots.
Version 1.0 of portsnap is in the FreeBSD base system since FreeBSD 5.5 and 6.1 and in the FreeBSD ports tree as sysutils/portsnap on older versions.
To install portsnap and use it for the first time:
# cd /usr/ports/sysutils/portsnap # make install clean # cd /usr/local/etc/ && cp portsnap.conf.sample portsnap.conf # portsnap fetch (this will download a large file) # portsnap extract (this will update the ports tree)
After that, using portsnap is easy:
# portsnap fetch # portsnap update
In order to avoid problems with “flash crowds” accessing the portsnap servers, portsnap fetch will not run from a cron job. Instead, there is a special command, portsnap cron, which waits for a random duration up to 3600 seconds and then functions just like portsnap fetch.
In addition, it is strongly recommended that portsnap update not be run from a cron job, since it is liable to cause major problems if it happens to run at the same time as a port is being built or installed. However, it is safe to update the ports INDEX files, and this can be done by passing the -I flag to portsnap. (Obviously, if portsnap -I update is run from cron, then it will be necessary to run portsnap update without the -I flag at a later time in order to update the rest of the tree.)
Adding the following line to /etc/crontab will cause portsnap to update its compressed snapshot and the INDEX files in /usr/ports/, and will send an email if any installed ports are out of date:
0 3 * * * root portsnap -I cron update && pkg_version -vIL=
Note: Consider replacing the "3" above with a random value between 0 and 23, in order to spread the load on the portsnap servers more evenly.
See also: updating the system