Syncthing on FreeBSD

According to its homepage Syncthing is:

[…] a continuous file synchronization program. It synchronizes files between two or more computers in real time, safely protected from prying eyes. Your data is your data alone and you deserve to choose where it is stored, whether it is shared with some third party, and how it’s transmitted over the internet.

In a way it does what Dropbox does, but without the central hub that Dropbox provides; Syncthing syncs directly between computers! And just as important, It works directly on FreeBSD

Basic Installation

As with most services on FreeBSD, a basic installation can be as quick as:

% pkg install syncthing
% sysrc syncthing_enable=YES
% service syncthing start

This will run Syncthing as user syncthing. And unless you happen to login in and work as user syncthing on your machine, this is likely not what you want. For Syncthing to sync your files, it needs to run as your own user.

Let’s stop the Syncthing service first before we continue:

% service syncthing stop

Running As Your Own User

Some packages provide a package message to display additional installation instructions. The syncthing package however, does not, as demonstrated by:

% pkg info -D syncthing
syncthing-1.15.1:

%

Where -D is short for --pkg-message

Find Configuration Instructions

Not to worry though. FreeBSD services are started by simple command scripts, also known as rc scripts. These scripts live in two locations:

Syncthing falls in the second category:

% ls -la /usr/local/etc/rc.d | grep syncthing
-rwxr-xr-x   1 root  wheel  1867 Apr 16 06:17 syncthing
-rwxr-xr-x   1 root  wheel  2775 Apr 16 06:17 syncthing-discosrv
-rwxr-xr-x   1 root  wheel  2439 Apr 16 06:17 syncthing-relaypoolsrv
-rwxr-xr-x   1 root  wheel  2563 Apr 16 06:17 syncthing-relaysrv

This time we knew where to look. But if you don’t or just want to know the files a package has installed on your system you can always run:

% pkg info -l syncthing
syncthing-1.15.1:
        /usr/local/bin/stdiscosrv
        /usr/local/bin/strelaypoolsrv
        /usr/local/bin/strelaysrv
        /usr/local/bin/syncthing
        /usr/local/etc/rc.d/syncthing
        /usr/local/etc/rc.d/syncthing-discosrv
        /usr/local/etc/rc.d/syncthing-relaypoolsrv
        /usr/local/etc/rc.d/syncthing-relaysrv
        /usr/local/share/doc/syncthing/AUTHORS
        /usr/local/share/doc/syncthing/LICENSE
        /usr/local/share/doc/syncthing/README.md
        /usr/local/share/licenses/syncthing-1.15.1/LICENSE
        /usr/local/share/licenses/syncthing-1.15.1/MPL20
        /usr/local/share/licenses/syncthing-1.15.1/catalog.mk

Where -l is short for --list-files

Anyway, the command script we are interested in, is /usr/local/etc/rc.d/syncthing. When viewing it, the top level comment section pretty much explains all the things we need:

% less /usr/local/etc/rc.d/syncthing
#!/bin/sh

# PROVIDE: syncthing
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf
# to enable this service:
#
# syncthing_enable (bool):      Set to NO by default.
#                               Set it to YES to enable syncthing.
# syncthing_home (path):        Directory where syncthing configuration
#                               data is stored.
#                               Default: /usr/local/etc/syncthing
# syncthing_log_file (path):    Syncthing log file
#                               Default: /var/log/syncthing.log
# syncthing_user (user):        Set user to run syncthing.
#                               Default is "syncthing".
# syncthing_group (group):      Set group to run syncthing.
#                               Default is "syncthing".

[...]

Specifying The User

From the above we can devise that to run Syncthing as our own user (user guido in my case), we should set syncthing_user and syncthing_group to guido (my group is also named guido):

% sysrc syncthing_user=guido
% sysrc syncthing_group=guido

Logging And Certificate Location

When we do that, Syncthing will no longer be able to write to its log file in /var/log. Nor will it be able to use the certificate it had generated on its first run in /usr/local/etc/syncthing/.

To remedy the logging problem we create, as user root, a new log directory in /var/log and assign its ownership to our user:

% mkdir /var/log/syncthing
% chown guido:guido /var/log/syncthing

With the new log directory created, we need to tell Syncthing where to put its log file:

% sysrc syncthing_log_file=/var/log/syncthing/syncthing.log

The problem with the certificates can be addressed by Syncthing itself. It will simply create a new certificate in the user’s home directory. I prefer to have that certificate in a specific directory so I set:

% sysrc syncthing_home=/home/guido/syncthing

Now we are ready to start the Syncthing service again:

% service syncthing start

When you open http://127.0.0.1:8384/ you will see Syncthing’s web interface. From here on you are ready to follow Syncthing’s own Getting Started Guide

Firewall Configuration

If you have a firewall configured, you will likely notice that Syncthing is rather slow in its syncing process. In that case it is probably bouncing sync traffic via a relay. To prevent that and allow Syncthing to discover its peers on your local network you will need to allow broadcasts on port 21027. In addition you should open port 22000 for both UDP and TCP for sync protocol traffic.

With the PF firewall this is easily done:

ext_if="lagg0"

set skip on lo0
scrub in

block in
pass out

pass in on $ext_if proto tcp from any to ($ext_if) port { ssh, domain, http, https, 22000 }
pass in on $ext_if proto udp to ($ext_if) port { domain, 22000 }
pass in on $ext_if proto udp to any port { mdns, 21027 }
pass in on $ext_if inet proto icmp to ($ext_if) icmp-type { unreach, redir, timex, echoreq }

All rules were already there in my specific configuration. I just had to add either 22000 or 21027 to them.

Conclusion

Configuring Syncthing is not much work, but you need to pay attention to:

In short (or TL;DR), it boils down to:

% pkg install syncthing
% sysrc syncthing_enable=YES
% sysrc syncthing_user=guido
% sysrc syncthing_group=guido
% mkdir /var/log/syncthing
% chown guido:guido /var/log/syncthing
% sysrc syncthing_log_file=/var/log/syncthing/syncthing.log
% sysrc syncthing_home=/home/guido/syncthing
% service syncthing start