Syncthing is a solution to share files across multiple devices, spanning most operating systems, including Linux, Windows, Mac and Android. It's open source and it is decentralized. It requires some set-up, however. I was reluctant at first, but it is one of the things that I did not know I needed.

I have started using it to sync my .kdbx password database file between my laptop and my phone and it proved to work reliably and near-instant. I made a lot of research to choose the right password manager for my needs and a possibility to store SSH keys in KeePassXC was a deal-maker for me. It looks like it is quire hard to implement this such functionality in the cloud-based solution. Yet people in the discussions mention Syncthing as a to-go tool to synchronize another type of files: photos.

Thus logically, with everything already set-up to synchronize one database file, I went on and added another folder that my phone uses to store fresh photos of whatever I find interesting enough to capture. It did not took me long time to became basically addicted to the fact that whatever I point my phone camera at is available in the laptop in a real time.

Centralizing decentralized

The first drawback of this set-up that I decided to tackle was that if one device if off-line for some time, it won't get the updates from the other device. If that other device is lost in the meantime, the data are lost. In reality, this would mean that if I lost my phone before my laptop gets connectivity, the photos would be lost. The situation with passwords and SSH keys is no different, yet the consequences could be even more dire, depending on the situation.

The lack of the central server lowers the cost but in the meantime it increases the risk that data would be lost, as we can see. Sow how does one solve this problem? Well, the solution is simple, as you already suspect. Take your favorite low-power ARM device, attach a reliable storage to it and let it always on. If this scenario seems to familiar to you, it is. Most people choose Raspberry Pi, that is usually just a drawer away, ready to be used.

Setting up an always-on device device for this task brings best of both worlds. I got centralized solution without the requirements that a conventional centralized services pose, such as public IP and too-reliable connectivity. Introducing a central node in a decentralized service removes the single point of failure. My setup is working without any problems, even when the Pi dies or loses connectivity for some time. It will eventually get synchronized with the phone or the laptop, once brought back to working state. It just makes sure there is almost always a point where data could synchronize to preventing them being lost.

Preparation

As I have already noted, for this recipe we need a stale ARM computer, headless. Next we need a storage media, a preferably a raw SSD or a HDD if you are vegan. Sprinkle a little bit of bootable media in to the mix. Now follow the instructions in the cookbook.

  1. The next step is to install the system and Syncthing itself, when logged in as root:
pacman -Syu syncthing
  1. Mount the storage media somewhere into the prepared directory, example:
mkdir /mnt/storage
mount /dev/sdXY /mnt/storage
  1. Make sure the storage media get automatically mounted on boot, example using UUID:
pacman -S arch-install-tools
genfstab -U /mnt/storage/ >> /etc/fstab

Note: You can remove the arch-install-tools package after this step. If you edit an fstab file manually, you do not even need it for the genfstab command in the first place.

  1. Create a system user syncuser without any login shell:
useradd --system --user-group --create-home --shell /usr/bin/nologin syncuser
  1. Allow only root and syncuser users to access storage media:
chown root:syncuser /mnt/storage
chmod 750 /mnt/storage

Note: A separate system user greatly limits unauthorized data manipulation in case some ransomware or a malicious user used SSH key-pair to enter the device from my laptop.

  1. Enable and start Syncthing service:
systemctl enable syncthing@syncuser --now
  1. Make Syncthing web GUI accessible over the network:
su -s /bin/bash -c 'vi /home/syncuser/.config/syncthing/config.xml' syncuser

Change the address from 127.0.0.1 to 0.0.0.0:

<gui enabled="true" ...>
	<address>0.0.0.0:8384</address>
	...
</gui>
  1. Harden your device properly, or at least restrict root login.

  2. Set up the firewall - Syncthing package provides the UPnP and GUI definitions for ufw

    • this step is optional:
pacman -S ufw
systemctl enable ufw --now
ufw default deny
ufw allow syncthing
ufw allow syncthing-gui
ufw limit ssh
ufw enable
  1. Done!