Four years have past, and my FreeBSD email server has keps on running without any problems. However, some people on IRC have recently been nagging me to support TLSv1.3 on my mailserver. Since the installation was done 4 years ago, it didn’t do 1.3 yet, just 1.2. I set out to do a relatively simple system update, which didn’t go as smooth as I had hoped. This tutorial post should help you avoid the mistakes I made, so your updates will go smooth.
The rest of this tutorial assumes you're running as the
Before we do anything wild, let’s do the obvious first step: backups. Since
this is a FreeBSD server, it uses glorious
ZFS as the filesystem, which allows us to
make use of
Which subvolumes to make snapshots off depends on your particular setup. In my
case, my actual email data is stored on
zroot/srv, and all the services and
their configurations are in
zroot/usr/local. My database’s data is stored on
zroot/postgres/data96. Additionally, I want to make a snapshot of
This will make a snapshot of each of these locations, for easy restoration in
case any problems arise. You can list all your snapshots with
zfs list -t
Your server is most likely hosted at a provider, not in your home. This means you won’t be able to just physically access it and retrieve the harddrive if things go really bad. You might not be able to boot single-user mode either. Because of this, you might not be able to restore the snapshots if things go really bad. In this case, you should also make a local copy of the important data.
The services and their configuration can be recreated, just follow the earlier
parts of this series again. The email data, however, cannot. This is the data
/srv/mail. You can make a local copy of all this data using
There’s one more thing to do, which I learned the hard way. Set your login
shell to a simple one, provided by the base system. The obvious choice is
/bin/sh, but some people may wrongly prefer
/bin/tcsh as well. During a
major version update, the ABI changes, which will temporarily break most of
the user-installed packages, including your shell.
Be sure to change the shell for whatever user you're using to SSH into this machine too, if any!
Updating the Base System
With the preparations in place in case things get royally screwed up, the
actual updates can begin. FreeBSD has a dedicated program to handle updating
the base system,
freebsd-update. First off, fetch any updates, and make sure
all the updates for your current version are applied.
Afterwards, set the new system version you want to update to. In my case, this
12.1-RELEASE, but if you’re reading this in the future, you most certainly
want a newer version.
This command will ask you to review the changes and confirm them as well. It should generally be fine, but this is your last chance to make any backups or perform other actions to secure your data! If you’re ready to continue, install the updates to the machine.
At this point, your kernel has been updated. Next you must reboot to start using the new kernel.
Once the system is back online, you can continue installing the rest of the updates.
When this command finishes, the base system has been updated and should be ready for use. Next up is updating all the software you installed manually.
Updating User-Installed Packages
Unlike GNU+Linux distributions, FreeBSD has a clear distinction between the
base system and user installed software. The base system has now been
updated, but everything installed through
pkg or ports is still at the old
version. If you performed a major version upgrade (say, FreeBSD 11.x to 12.x),
the ABI has changed and few, if any, of the user-installed packages still work.
Binary Packages using
Binary packages are the most common packages used. These are the packages
pkg itself doesn’t even work. Luckily,
pkg-static, which is a statically compiled version of
intended to fix this very problem. Let’s fix up
pkg itself first.
That will make
pkg itself work again. Now you can use
pkg to update package
information, and upgrade all packages to a version that works under this
A particular package that was installed through
pkg, PostgreSQL, just got
updated to the latest version. On FreeBSD, the data directory used by
PostgreSQL is dependent on the version you’re running. If you try to list
databases now, you’ll notice that the
pgdump, upgrade, restart and
import. However, I find it much cleaner to use FreeBSD jails to solve this
My original installation used PostgreSQL 9.6, you may need to update some version numbers accordingly!
I generally put my jails in a ZFS subvolume, so let’s create one of those first.
This will create a new subvolume at
bsdinstall, a clean FreeBSD installation usable by the jail can be set up
here. This command will give you some popups you may remember from installing
FreeBSD initially. This time, you can uncheck all boxes, to get the most
bsdinstall finishes, you can configure the jail. This is done in
/etc/jail.conf. If this file doesn’t exist, you can create it. Make sure the
following configuration block is written to the file.
Now you can start up the jail, so it can be used.
Using the host system’s
pkg, you can install PostgreSQL into the jail.
Now you just need to make the data directory available to the jail, which you
can most easily do using
Now everything should be ready for use inside the jail. Let’s head on in using
Once inside the jail, you can start the PostgreSQL service, and dump the
This will write the dump to
the host system. You can leave the jail and close it down again.
This dump can be imported in your updated PostgreSQL on the host system. Connect to the database first.
Then, recreate the user, database and import the data from the dump.
Packages from Ports
With all the binary packages out of the way, it’s time to update packages from
ports. While it is very possible to just go to each port’s directory and
manually update each one individually, I opted to use
portupgrade. This will
need manual installation, but afterwards, we can rely on
portupgrade to do
the rest. Before doing anything with the ports collection, it should be
updated, which is done using
Once this is done, you can go to the
portupgrade directory and install it.
Now, to upgrade all other ports.
Be sure to double-check the compilation options that you are prompted about! If you’re missing a certain option, you may miss an important feature that is required for your mailserver to work appropriately. This can be easily fixed by recompiling, but a few seconds checking now can save you an hour figuring it out later!
Now that all user-installed software has been updated too, it’s time to
finalize the update by running
freebsd-update for a final time.
You can return to your favourite shell again.
And you can clean up the ports directories to get some wasted space back.
I would suggest making a new snapshot as well, now that you’re on a relatively clean and stable state.
And that concludes your system update. Your mailserver is ready to be neglected for years again!