Syncthing
Posted on Thu 11 October 2018 in linux
Syncthing is an open-source synchronization tool that allows the decentralized sharing of files between devices. In contrast to other synchronization services that store your data somewhere on servers in the cloud, Syncthing operates in a P2P-fashion, i.e. without such a central server, by just transmitting the data between your own devices directly. All of the used communication is encrypted via TLS to prevent eavesdroppers to gain access to the data. Besides, all participating devices must be authenticated via a strong cryptographic certificate so that only explicitly allowed devices can join the synchronization.
Since Syncthing is implemented in go it is available for all major operating systems, including Linux, Windows, MacOS, BSD-Variants. Apart from this there is also an Android App to sync files to mobile devices.
In the following, an advanced Syncthing setup is discussed that focuses on the current Debian version Stretch.
Base Setup
Since Debian packages tend to become outdated fast, while Syncthing is under heavy development, it is recommended to make use of the latest Syncthing version. Luckily, Syncthing provides its own Debian repository that can be easily integrated as follows:
# make sure that https transport is supported
sudo apt install apt-transport-https
# add the Syncthing's developers gpg key
curl -s https://syncthing.net/release-key.txt | sudo apt-key add -
# Add the "stable" channel to the APT sources:
echo "deb https://apt.syncthing.net/ syncthing stable" | sudo tee /etc/apt/sources.list.d/syncthing.list
# Update and install Syncthing:
sudo apt update
Syncthing client
To synchronize files the Syncthing client must be installed on two or more devices. The client can simply be installed as follows:
sudo apt install syncthing
Afterwards, the application can be started by calling syncthing
. The
application will fire up and open the port 8384
that provides a webpage that
can be locally access by pointing the browser to
http://127.0.0.1:8384 (on a desktop system the
webpage will automatically be opened by the default browser).
For the configuration of the web application check out the official Syncthing introduction.
Since for testing purposes this is nice, normally a syncing service should
run in the background. A simple way to pursue this is to setup a systemd
service for your user with the by Syncthing provided service files.
# start the service and make sure it runs correctly
sudo systemctl start syncthing@myuser.service
sudo systemctl status syncthing@myuser.service
# enable the service for an automatic start on boot
sudo systemctl enable syncthing@myuser.service
If you are only using Syncthing locally, just configure the shared directories via the webpage. In the case that you want to expose the Syncthing port to a network, make sure to set a password for the web UI and to enable https support in the settings.
Additional Services
When files should be synchronized between devices that are located in different subnetworks, the devices can neither locally detect whether they are online or not nor exchange data. Syncthing provides two mechanisms to circumvent these problems: the discovery server and the relay server. While the discovery server allows a device to state its current online status and reply the status to other devices on request, the relay server deals with the intermediate relaying of data packets between two devices that cannot directly reach each other. Although, Syncthing provides both services for all users and all of the communication is end-to-end encrypted, you may become paranoid to share those services with all the other users. Alternatively, Syncthing provides complementary to the client both other services as well for a setup in custom environments so that individual discovery and relay services can be setup for private use.
For that reason, in the following, the private setup of the discovery server and the relay server are discussed for the paranoids of us ;-)
Prerequisites
Since it is strongly discouraged to run such services as root
user, a
dedicated syncthing
user is created as follows:
sudo useradd -r -s /bin/false syncthing
The user will just be used to run the services, so the user can neither login nor a home directory is provided.
Moreover, a corresponding directory for the data is created and the permissions are set for the new user:
sudo mkdir /var/lib/syncthing
sudo chown syncthing:root /var/lib/syncthing
When using letsencrypt certificates ensure that the syncthing
user can
access the corresponding certificates. This can, for example, be implemented
by adding the user to the ssl-cert
group and adapting the directory
permissions correspondingly.
sudo adduser syncthing ssl-cert
sudo chown root:ssl-cert /etc/letsencrypt/{archive,live}
sudo chmod g+xr /etc/letsencrypt/{archive,live}
Discovery Server
Using the Debian repository, the discovery server can be installed as follows:
sudo apt install syncthing-discosrv
To run the discovery server in the background with the syncthing
user, a
new system service will be created. Sadly, there is no template so a custom
service must be defined:
A new /etc/systemd/system/stdiscosrv.service
file is created with the following
content:
[Unit]
Description=Syncthing Discovery Service (stdiscosrv)
After=network.target
[Service]
Type=simple
User=syncthing
ExecStart=/usr/bin/stdiscosrv -cert /etc/letsencrypt/live/<mydomain>/fullchain.pem -key /etc/letsencrypt/live/<mydomain>/privkey.pem -db-dir /var/lib/syncthing/discosrv.db -http
Restart=on-failure
SuccessExitStatus=2
PrivateDevices=true
ProtectSystem=full
ProtectHome=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
Make sure to adapt the certificate and private key for the file.
Start the service:
# reload the systemd files
systemctl daemon-reload
# start the discovery service and make sure that it runs correctly
sudo systemctl start stdiscosrv
sudo systemctl status stdiscosrv
# start the service on next boot automatically
sudo systemctl enable stdiscosrv
For a simple access a reverse proxy for nginx is configured. Create the
/etc/nginx/sites-available/disco
site file with the following content:
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-SSL-Cert $ssl_client_cert;
upstream disco.yourdomain.de {
# Local IP address:port for discovery server
server 127.0.0.1:8443;
}
server {
server_name disco.yourdomain.de;
listen 80;
return 301 https://$host$request_uri;
}
server {
server_name disco.yourdomain.de;
listen 443 ssl http2;
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4';
ssl_prefer_server_ciphers on;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_certificate /etc/letsencrypt/live/<yourdomain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<yourdomain>/privkey.pem;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
add_header Strict-Transport-Security "max-age=31536000";
ssl_verify_client optional_no_ca;
location / {
proxy_pass http://disco.yourdomain.de;
}
}
Make sure to adapt the domain and your certificate details. Then, activate the nginx page and restart the server.
ln -s /etc/nginx/sites-available/disco /etc/nginx/sites-enabled/disco
systemctl restart nginx
The discovery https://disco.yourdomain.de
can now be set in the client's
configuration.
Relay Server
Similarly, the relay server can be installed using the Debian repository:
sudo apt install syncthing-relaysrv
Create a new /etc/systemd/system/strelaysrv.service
file with the
following content:
[Unit]
Description=Syncthing Relay Service (strelaysrv)
After=network.target
[Service]
Type=simple
User=syncthing
ExecStart=/usr/bin/strelaysrv -keys /var/lib/syncthing -pools=""
Restart=on-failure
SuccessExitStatus=2
PrivateDevices=true
ProtectSystem=full
ProtectHome=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
The pools=""
ensures that the relay server stays private and does not
join other existing default pools.
Start the service:
# reload the systemd files
systemctl daemon-reload
# start the relay service and make sure that it runs correctly
sudo systemctl start strelaysrv
sudo systemctl status strelaysrv
# start the service on next boot automatically
sudo systemctl enable strelaysrv
You can check the relay server by visiting
http://
The client needs to be pointed to access the relay server.
relay://<yourdomain>:22069/?id=<your ID>
Disclaimer
This setup was written based on an already running server so that there might be steps that I forgot to mention here. Feel free to contact me if there are any problems with this tutorial.
Besides, check the official documentation on https://docs.syncthing.net to get more information about the configuration details.