FreeBSD on Raspberry Pi 2

This is a runbook for setting up a FreeBSD file server on a Raspberry Pi 2 with a USB-attached SSD.

Keep the FreeBSD docs handy:

Download the latest image from: (I would rather use RELEASE than CURRENT, but 10.1 doesn’t offer a RPi2 image. Here’s to life on the bleeding edge!)

Decompress it with unxz, and dd it to the sd card.

Boot the Pi.

Default accounts:

u: root p: root

u: freebsd p: freebsd

Reset the root password. su and passwd.

Add your user account with adduser. Add it to the wheel group.

Disable the “freebsd” user with pw lock freebsd.

Set a static IP by editing /etc/rc.conf.local:

ifconfig_ue0="inet netmask"

(Manually add the default route until next reboot: route add default

Set up ntp (especially because Pi doesn’t have hardware RTC). Run ln -s /usr/share/zoneinfo/America/Detroit /etc/localtime. Edit /etc/rc.conf.local:


Run service ntpd start.

Install some software. portsnap fetch and portsnap extract. cd /usr/ports/sysutils/tmux; make install clean cd /usr/ports/security/sudo; make install clean cd /usr/ports/editors/vim; make install clean cd /usr/ports/net/rsync; make install clean cd /usr/ports/ftp/wget; make install clean cd /usr/ports/shells/bash; make install clean cd /usr/ports/devel/git; make install clean cd /usr/ports/irc/irssi; make install clean cd /usr/ports/ports-mgmt/portmaster; make install clean

Search ports like cd /usr/ports/ and make search name=foo. May need to get an index first like make fetchindex.

(I’d rather use binary packages, but they don’t seem to be available. Maybe once Pi2 gets into STABLE.)

After initial setup of the ports collection, normal updates can be done with portsnap fetch update. Do upgrades with portmaster -a.

Run makewhatis to rebuild the man page index. (apropos and whatis work, but not man -k. Why?)

Add user account to sudoers.

Change user account shell to bash with vipw.

Note that the default tmux shell is set in ~/.tmux.conf like:

set-option -g default-shell /usr/local/bin/bash

After adding ~/.bashrc, do ln -s ~/.bashrc ~/.bash_profile.

(BSD ls differs from GNU ls. -G instead of –color. Instead of dircolors, export LSCOLORS=gxfxfgxgbxdgxgBxBxegeg.)

Run ssh-keygen as user. Copy key from .ssh/ to remote server(s).

Partition, format, and mount usb ssd drive

Find the device with dmesg | grep -A6 umass. Mine seems to be da0.

Look for existing partitions with gpart list.

Delete existing partition: gpart delete -i 1 da0.

Add a FreeBSD ufs partition: gpart add -t freebsd-ufs da0.

Format the partition: newfs -U -t /dev/da0p1. (-t is for TRIM.)

mkdir ssd

Add to /etc/fstab:

/dev/da0p1      /ssd    ufs     rw,noatime      0       2

Do mount /ssd.

Add swap

Create a 4Gb swap file on the ssd:

dd if=/dev/zero of=/ssd/swap bs=128k count=32768
chmod 0600 /ssd/swap

Add to /etc/fstab:

md99    none    swap    sw,file=/usr/swap0  0   0

And turn on swap: swapon -aq.

Dealing with dynamic public IP address

Easiest to set up: scp the IP to a server with a fixed address. On the pi, run something like this shell script as an hourly cron job:

/usr/bin/host | /usr/bin/grep "has address" | /usr/bin/awk '{print $NF}' > /tmp/ip.txt
/usr/bin/scp -q /tmp/ip.txt


(I wanted to tunnel NFS over SSH, but never got it working. I ended up using sshfs on the client instead. Nevertheless, the following NFS stuff works OK for LAN, albeit with some UID/GID mismatches.)

On the pi/server, edit /etc/exports (exports(5)) to add:

/ssd localhost

Add to /etc/rc.conf.local:


Start nfsd, rpcbind, and mountd with service nfsd start.

Make a mount point on the client: mkdir /pi.

mount -v -t nfs pi:/ssd /pi

”/ssd” is the path on the server we want to mount.

Firewall the pi with pf