Using ports

By Kurt Seifried, [email protected]

The ports collection is the primary interface for installing additional software on OpenBSD. It consists of makefiles, information about the programs, and patch files needed to compile them successfully on OpenBSD. You will need the compXX.tgz (where XX is your version of OpenBSD) installed to compile software in ports. However you can compile ports on a machine and take the installation package it creates and use it on another machine, allowing you to quickly deploy software to numerous systems.


Downloading and installing the ports tree

Ports consists of a large tarball available on OpenBSD ftp sites and the CD's. You download "ports.tar.gz" and unpack it in "/usr/" so that you have a tree of directories and files in "/usr/ports/" (hence the name "ports tree").

# ftp
Connected to
220-                 Welcome to SunSITE Alberta
220-     at the University of Alberta, in Edmonton, Alberta, Canada
220- All connections to and transfers from this server are logged. If 
220- you do not like this policy, please disconnect now.
220- You may want to grab the index file called "ls-lR.gz" in /pub.  It is 
220- updated nightly with the contents of the ftp tree.  
220-     If you have any questions, hints, or requests, please email
220-            [email protected]
220 merlin FTP server (SunOS 4.1) ready.
Name ( anonymous
331 Guest login ok, send your email address as password.
230- Guest login ok, access restrictions apply.
230- Local time is: Fri Jun 14 15:01:27 2002
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd pub/OpenBSD/3.1
250 CWD command successful.
ftp> get ports.tar.gz

Followed by unpacking and untaring it:

# gzip -d ports.tar.gz 
# cd /usr
# tar -xf /root/ports.tar


Finding things in ports

There are a number of ways to find things in ports. Commonly simply cd'ing to the appropriate directory and issuing an ls will list likely candidate programs, with security programs in the security directory, network packages in net and so on. If you are looking for a specific application or a keyword, such as "vpn" then you simply use the make command in the root of the ports tree:

# cd /usr/ports
# make search key=vpn

Port: pptp-1.0.2
Path: net/pptp
Info: PPTP client package for Microsoft VPN servers
Maint: Reinhard J. Sammer <[email protected]>
Index: net
Archs: any

Please note that keywords may not be intuitive, for example when searching for an email server using the keyword "smtp" results in only one port being listed, "smtpclient". Using more generic keywords will result in more results, of which typically only the name, path and information fields are wanted. To list only these portions of the ports info when using search simply use grep to cull the results down. To list all the web browsers for example simply use the following command:

# make search key="web browser" | grep "^Port:" -A 2
Port: dillo-0.6.6
Path: www/dillo
Info: Fast and light gtk-based web browser
Port: hotjava-3.0
Path: www/hotjava
Info: Sun's Hotjava web browser
Port: konqueror-20020311
Path: www/konqueror-embedded
Info: stand-alone web browser
Port: w3m-0.3
Path: www/w3m
Info: pager/text-based web browser
Port: w3m-0.3-image
Path: www/w3m,image
Info: pager/text-based web browser
Port: ja-w3m-0.3
Path: www/w3m,japanese
Info: pager/text-based web browser
Port: ja-w3m-0.3-image
Path: www/w3m,image,japanese
Info: pager/text-based web browser
Port: w3m-0.3.20020311-m17n
Path: www/w3m,m17n
Info: pager/text-based web browser
Port: w3m-0.3.20020311-image-m17n
Path: www/w3m,image,m17n
Info: pager/text-based web browser

You can also use multiple search terms by separating them with a "|":

# make search key="nntp|smtp|vpn" | grep ^Port: -A 2
Port: smtpclient-1.0.0
Path: mail/smtpclient
Info: simple SMTP client
Port: pptp-1.0.2
Path: net/pptp
Info: PPTP client package for Microsoft VPN servers
Port: newsfetch-1.21
Path: news/newsfetch
Info: download news articles from NNTP server
Port: p5-News-Article-1.13
Path: news/p5-News-Article
Info: perl module for accessing NNTP articles
Port: tin-1.4.5-nntp_only
Path: news/tin,nntp_only
Info: full-screen easy to use Usenet reader


To find the maintainer of a specific package you can search the Makefile, or use the make command to list them:

# cd /usr/ports/security/nessus
# grep "^MAINTAINER" Makefile


Building and installing things from ports

Once you have found what you want you will need to build the port and install it. Many ports require other things in ports to be present, such as "gmake", if such a dependency is present when you issue the "make" command the dependencies will automatically be built first and installed. This can lead to some problems on non standard systems that require specific make options, you should first build things in /usr/ports/devel/ that you will probably need such as "gmake" or any language specific items like "ORBit" or "jdk". To build a port simply cd into the appropriate directory and issue the make command:

# cd /usr/ports/security/gpgme/
# make

The first thing that will happen is any dependencies are satisfied first. Then it will download the package from the ftp or web site if it is not present in /usr/ports/distfiles. The package is then uncompressed and un-tar'ed as needed, any patch files are applied, and the package is then built using the appropriate tools (make and Makefiles, a shell script, etc.). At this point the software has been built but not yet installed. If the last thing you see are error messages then you will need to take corrective actions (try using an older or newer version of the software, check the mailing lists, etc.).

To install the software you will need to issue a second command, "make install":

# make install

The first thing you will see is a line such as:

===> Faking installation for gpgme-0.3.4

And the last set of lines you should see will be something like:

===> Building package for gpgme-0.3.4
Creating package /usr/ports/packages/i386/All/gpgme-0.3.4.tgz
Using SrcDir value of /usr/ports/security/gpgme/w-gpgme-0.3.4/fake-i386/usr/local
Creating gzip'd tar ball in '/usr/ports/packages/i386/All/gpgme-0.3.4.tgz'
===> gpgme-0.3.4 depends on: gnupg-* - found
===> Installing gpgme-0.3.4 from /usr/ports/packages/i386/All/gpgme-0.3.4.tgz

Essentially the system creates the installable package first and then install it, rather then installing from the source code directly. This ensures consistency across systems and also provides one last sanity check, allowing the ports maintainer to control the location files are installed to rather then the author of the software (i.e. /bin vs.s /usr/local/bin vs.s. /opt/bin vs.s. /nfs-exports/openbsd/3.1/bin and so on).


Using "flavors"

Some ports support "flavors", this can range from something simple like building a program without X windows support (for example Nessus which includes a server component, and client components) to which version of a program to use (such as "pgp" or "pgp5"). Other flavors commands can include keywords such as "static" (i.e. to build the binary statically and not use dynamically linked libraries). Flavors are extremely simply to use, you append the command "flavor='foo'" to the make command, such as:

# make flavor='no_x11'

The quickest way to find if a port has flavors is to simply grep the Makefile for "FLAVORS":

# grep FLAVORS /usr/ports/net/bind9/Makefile
/usr/ports/net/bind9/Makefile:FLAVORS= debug static threads

Thus you can see that Bind 9 can be built using threads, statically or with debugging capabilities. Typically flavors are not required, the major exception being "no_x11" which is very common on headless servers and the like.


Installing precompiled packages

Precompiled software packages for OpenBSD are available on the official vendor CD's, and any packages you build in ports will be available in /usr/ports/packages/ARCHITECTURE/All/. Some software vendors also make binary packages available to spare users the trouble or to prevent source code from being distributed. To install such precompiled packages simply use the "pkd_add" command:

# pkg_add -v gpgme-0.3.4.tgz
Requested space: 480296 bytes, free space: 10443402240 bytes in /var/tmp/instmp.vNzip25517
pkg: Handling dependencies for gpgme-0.3.4
checking gnupg-* (gnupg-1.0.6) -> gnupg-1.0.6
Package `gpgme-0.3.4' depends on `gnupg-1.0.6'
- `gnupg-1.0.6' already installed
extract: Package name is gpgme-0.3.4
extract: CWD to /usr/local
extract: /usr/local/bin/gpgme-config
extract: /usr/local/include/gpgme.h
extract: /usr/local/info/
extract: /usr/local/lib/libgpgme.a
extract: /usr/local/lib/
extract: /usr/local/share/aclocal/gpgme.m4
extract: /usr/local/lib/
extract: execute '/sbin/ldconfig -m /usr/local/lib'
extract: execute 'install-info --info-dir=/usr/local/info /usr/local/info/'
extract: CWD to .
Attempting to record package into `/var/db/pkg/gpgme-0.3.4'
Attempting to record dependency on package `gnupg-1.0.6'
Package `gpgme-0.3.4' registered in `/var/db/pkg/gpgme-0.3.4'

You can change the location used to unpack the file using the "-t" option, if you are installing a large package to /usr/ for example and /tmp is on a separate disk it may be faster to unpack to /usr/ and install from there then from /tmp.


What to do when things won't build

Ports will almost always build, but that is not to say they will always work. Some of the more common problems are:

The first thing to check is the source code, did it get downloaded, if yes it should be present in "/usr/ports/distfiles". This can be due to the source code being modified but not renumbered, ports files usually have an MD5 and SHA1 signature of the source code tarball, if they don't match the port will not compile it by default. Changing the Makefile to ignore this signature and compile in any event is dangerous. Please see more on this in the security section.

The next thing to do is check the output of the compile, common errors include things like "can't find library..." or "patch file hunk failed to apply..." most of these messages are reasonably self explanatory, if patch files aren't applying properly then either the patch file or the source code has changed enough to break it, manually checking files and modifying the patch is one approach, simply downloading newer software another. Another common reason for these errors is something on the system is broken, have you recently removed any files or directories to save space? This is a common mistake that can lead to problems. You should also check what version of OpenBSD you are using, if it's 2.x-stable then it may be time to upgrade, GCC is currently going through major changes as vendors start to ship the next major release (3.x), and many software packages have errors that GCC 2.x will accept and process but that GCC 3.x will not (being somewhat more strict in it's input).


Security issues in ports

Ports relies primarily on third party software vendors ranging from individuals to organizations such as the Apache group. While efforts are made to ensure the code is reasonable correct the software in ports is not audited to nearly the degree that OpenBSD is. Furthermore there have been several incidents of sites such as being broken into and software packages hosted there being modified, ranging from additional commands in the Makefiles to actual modification of the source code. For this reason OpenBSD includes MD5 sums of the packages, if modified the MD5 sum will not match and a warning will be issued, DO NOT IGNORE THESE WARNINGS. While they are often false positives due to a package being updated they should be investigated before continuing as you are putting your system at risk.

You can change ownership of the "/usr/ports" directory to a non root user such as "portuser" and then compile all packages as this user. You will also want to create /etc/mk.conf and add the following line to it:


This will greatly simplify the task of creating ports as a non root user. The user building ports should of course have sudo access.

Building ports as a non root user decreases the risk of a security incident, several programs in ports were found to have compromised distribution source code which created a root shell bound to the network if the port was compiled as root, if the port had been compiled as a user this would not have been an issue. However if an attacker can subvert your ports files, or the software you download they can compromise your system since the compiled package must be installed by root in any event. Please note this will break some ports when trying to compile them or create the packages as non-root users will not be able to set file permissions to other users or create setuid/setgid files.



Bandwidth saving techniques for ports

There are a number of ways to save bandwidth when making ports files. The first most obvious way is to purchase the OpenBSD CD's which come with a wide variety of prebuilt packages such as bash and emacs and other commonly used software. The second major bandwidth saving technique is to keep a copy of the source code required for the build locally, you can then use it by copying it into /usr/ports/distfiles/, or by making it available on a local server and modifying the locations in the Makefile for the program. This is ideal for administrators with multiple architectures or systems spanning multiple version of OpenBSD and libraries who wish to install the latest version of emacs for example on all their systems. The third method is to take the compiled packages, stored in /usr/ports/packages/ARCHITECTURE/All/ and copy them over to other systems and then use "pkg_add" to install them, this also saves on compiler time.



Last updated on 6/13/2002

Copyright Kurt Seifried 2002 [email protected]