Create a Time Machine backup server with netatalk on FreeBSD

Motivation

While building a NAS for my parents, I came across an easy way to build a Time Machine backup solution. They run OS X on all machines and want to back up all data to their NAS.

We will be using Netatalk3.x, which allows us to create file shares for OS X to provide a simple solution for system backups.

Kernel tuning

Just like setting up a samba server on FreeBSD, there are some kernel settings that should be tweaked to allow more files to be opened at once. Edit /etc/sysctl.conf and add the following lines:

kern.maxfiles=25600
kern.maxfilesperproc=16384
net.inet.tcp.sendspace=65536
net.inet.tcp.recvspace=65536

Also, we should make sure that asynchronous I/O is enabled. This can be accomplished by adding the following line to the file /boot/loader.conf:

aio_load="YES"

Most of the time asynchronous I/O is enabled by default. To get it working if it is not enabled by default and without restarting, additionally execute the following command:

kldload aio

Installation

We will us prebuilt binaries, so we’re using pkg, but you can also compile from /usr/ports. We need to install netatalk3 and nss_mdns:

pkg install netatalk3 nss_mdns

To ensure that mdns will work, we also need to change the line starting with hosts: in /etc/nsswitch.conf:

hosts: files mdns dns

We also need to set up the configuration file for netatalk located at /usr/local/etc/afp.conf. Here’s mine:

;
; Netatalk 3.x configuration file
;
;
[Global]
; Global server settings
vol preset = default_for_all_vol
log file = /var/log/netatalk3.log
log level = default:warn
host allow = 192.168.1.0/24
hostname = Daedalus
mimic model = Xserve
disconnect time = 1
;
;
[default_for_all_vol]
file perm = 0640
directory perm = 0750
cnid scheme = dbd
;
;
[Homes]
basedir regex = /usr/home
valid users = bms
;
;
[TimeCapsule]
time machine = yes
path = /storage/timecapsule/$u

I have restricted the subnet allowed to access the network volumes with the ‘host allow’ variable. Please make sure that the subnet you are connected to matches this configuration file. $u is a default variable that will add the logged in user to the path string.

Afterwards we can enable all services in /etc/rc.conf and start them:

sysrc dbus_enable=YES
sysrc avahi_daemon_enable=YES
sysrc netatalk_enable=YES

service dbus start
service avahi-daemon start
service netatalk start

note that if you do not start these services in rc.conf you will have to use ‘onetstart’ instead of ‘start’ with the ‘services’ command

Now we need to create the user(s) specified in the config file to allow them to login. They are identified by their respective system user, so you can create them using adduser. I decided to not give them a login shell so I chose nologin. Now you can connect to those shares. Keep an eye on /var/log/afpd.log if something fails.

Enabling on OS X

You might need to execute the following command on your clients to get your share listed in the Time Machine preferences pane:

defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1