How to build a Syncthing MSI package for distribution #syncthing-msi

Long story short:

  • This topic should share my existing work on an MSI package which can be used, for example, to distribute Syncthing easily in Windows Domain Environments or to give friends an “easy to install and connect to your server” setup experience.

  • As I guess every Syncthing user has other demands when it comes to Syncthing’s configuration. For example, some users may like relaying and global discovery and others like to strictly use static IP connections or local site connections only. For that reason, I’ve put everything into BATCH files. If you need to “BUILD YOUR OWN”, just change the port numbers and/or xml setting lines in the batch to fit your needs :-).

  • The build script I’m personally using to bundle Syncthing into a MSI already “lives” for a long time. I’ve now decided to improve it to reproducibly build with “live-downloaded” packages instead of statically distributing my local set of build (portable EXE) tools. This should also head forward if later someone like to integrate the script into an official Syncthing build server.

I’ll now showcase where to find the MSI build script and how to use it.

References:

HOW-TO: Build your OWN Syncthing MSI package

  1. Head to my batch repo at https://github.com/Catfriend1/syncthing-msi/releases/tag/v1.4.0 and download the GIT workspace from https://github.com/Catfriend1/syncthing-msi/archive/v1.4.0.zip .

  2. Extract the downloaded “syncthing-msi-1.4.0.zip” to “C:\Temp”. image image

  3. The folder “C:\Temp\syncthing-msi-v1.4.0” will open after extraction. image

  4. Double-click to launch “wix_build_msi.cmd”. The script will download portable prerequisites like GNU sed, Non-sucking-service-manager, Microsoft Sigcheck64, Syncthing and WiX Toolset. It will then build the MSI package using the latest Syncthing win-amd64 version - at time of writing v1.4.0. image

  5. Close the build output console window and look at your “C:\Temp\syncthing-msi” folder. Notice the file “Syncthing_v1.4.0.msi” was created. image

Done, your MSI package is ready for interactive installation or domain deployment via group policy.

HOW-TO: Install the Syncthing MSI package for ALL users running with “root” permissions. In Windows we call this permission level a “SYSTEM” service.

WARNING: You should FIRST consider how you secure Syncthing’s Web UI interface before deploying the package to corporate clients. With Syncthing’s default setting, the Web UI is reachable from localhost only (http://127.0.0.1:8384) and has NO password set until YOU set one. So be warned.

TIP: I recommend to install the MSI package on a virtual machine if this is your first try. So you can first see if it fits your needs or if you require editing the default Syncthing settings in the BATCH script.

  1. We’ve already built “Syncthing_v1.4.0.msi” during the how-to above. Let’s double click it to install it. image

  2. The installer may ask for administrative permission to setup the Windows service called “Syncthing” and an incoming firewall rule to get you starting. image

  3. Continue and wait until the installation completed. image

After setup is complete, the Syncthing service should be running. You could verify that - optionally - by looking in Windows services from the Control Panel.

  1. Open Windows start menu and look for “Syncthing Web UI” to setup a password for your locally installed Syncthing instance.

image

Go to “Actions” > “Settings”, flip the tab to “GUI” and fill in the password for the Admin UI. Then, hit “Save”.

image

You can now start to configure your Syncthing instance to your needs - just as you would do it with every common Syncthing instance.

==============

For reference: The MSI package currently modifies the following parts on your disk and Windows control panel:

  1. Installation folder is created

image

This is where your Syncthing binary files and database reside. You could technically upgrade the Syncthing instance, but currently it’s disabled by the MSI package as I personally like to upgrade our corporate environment with a new MSI package instead to equally determine the time when the upgrade arrives.

  1. Windows service is created so Syncthing starts delayed ~ 2 minutes after boot

  1. Firewall rule is created to allow local discovery and incoming connections for “syncthing.exe”

HOW-TO: How to easily connect family members or friends to your Syncthing server using a DynDNS address (with port forwarding set up).

  1. You already have “Syncthing_v1.4.0.msi” in your hands.

  2. Rename the file according to this scheme:

Syncthing_v1.4.0__[SYNCTHING_SERVER_DEVICE_ID]+[SYNCTHING_SERVER_DYNDNS]+[SYNCTHING_SERVER_TCP_PORT].msi

Example:

  • My Syncthing server is hosted at “catfriend-home.dyndns.org
  • The tcp port is configured to the default port number 22000.
  • The server’s Syncthing device ID is “CF6WMOG-F4RHVKW-2FTJONJ-GJ3FZQS-YW5TJVW-VDDT6ZQ-EVJ2WDP-RL4QZQO”.

Resulting filename:

Syncthing_v1.4.0__CF6WMOG-F4RHVKW-2FTJONJ-GJ3FZQS-YW5TJVW-VDDT6ZQ-EVJ2WDP-RL4QZQO+catfriend-home.dyndns.org+22000.msi
  1. Run a test MSI installation on a virtual machine or from a PC outside your local network.

image

  1. Open “Syncthing Web UI” from Windows start menu to see if it worked correctly.

image

image

You now see that the MSI installer automatically added your Syncthing server to the “Remove Devices”. This will cause to dial out to your server, so you just need to accept the requests coming from your friends/family computers there. If you share some folder with them, they’ll get the common Syncthing popup message on the Web UI which asks them to accept or ignore the folder. If they decide to add the folder, they’re automatically suggested to put it in “C:\Server\Sync”.

image

I’m currently on the trip to make my MSI to install Syncthing as a service better. If there’s interest, when I reach the point where I require less third-party utitilies and have configurable flags, e.g. for ports and connections we could get together in a discussion if there’s a chance of official MSI bundling. I still need to rework the setup process to be only dependent on the official syncthing.exe+nssm+batch. I also consider giving special protection to the folder where Syncthing places its secret keys and config. In my first draft, every normal user without admin priv could read the key files. Changing the port through the web ui made the link to it on the start menu invalid. I’ll report back when I’ve improved at that points.

3 Likes

… and here’s the “second gen” MSI where I think I’ve successfully improved a lot of things in regard to packaging Syncthing.

Link: https://github.com/Catfriend1/syncthing-msi/releases/tag/v1.5.0

Two highlights in summary:

  1. The package got a new strategy of “Do your own Syncthing”. It bundles the official “Syncthing.exe” keeping as much of the “config.xml” maintain-able from an admin perspective. You can one-shot-apply your preferred “config.xml” settings or force certain settings on every upgrade that is enrolled using the MSI package (override mode). Double-clicking or GPO-deploying the MSI uses default settings (see below). You can customize by using MSI command-line switches or using the free tool “Microsoft Orca” to edit the MSI properties so you have your “own package” in the end.

image

In Orca, go to “Property” on the left side of the window and then edit the properties according to your preference.

Example:

*** SECURITY NOTICE ***

Do NOT set REMOTE_WEB_UI without ensuring you’ll also set up a Web UI password immediately after deployment, e.g. through your own batch script. With Syncthing’s default, it would leave the web UI open with no password to every machine on your network and/or internet.

  1. The Syncthing service is now pre-configured to run under the “LocalService” account which improves security by avoiding to give it the “full” SYSTEM account access. It can access the default path “C:\Server\Sync” without any need to manually adjust ACL on folders with Windows Explorer. The C: drive also works in regard to add a new folder “C:\my-synced-docs” if your system is a common Windows installation. For sensitive paths like C:\Windows[subfolder], C:\Users[subfolder] the admin/user has to explicitly add “LocalService” to the folder’s permission set to allow access.

Changelog:

  • Replaced third-party tool “sed.exe” by “psreplace.cmd” using PowerShell
  • Removed build dependency “sigcheck.exe”, it was replaced by PowerShell
  • Added helper script “syncthing_grant_folder_access.cmd”
  • Added helper scripts to force a database recheck on next service startup “Create syncthing_strecheckdbevery_{off|on}.cmd”
  • Added auto-detection of Syncthing’s web UI port to open the correct URL in the browser in case the user changed the port after the initial installation.
  • Hardening and security have been improved. The “Syncthing” service is now configured to run under the “LocalService” account (instead of “NT AUTHORITY\SYSTEM”). Additionally, Syncthing’s home directory (C:\Server\Syncthing\appdata) can only be accessed by the following built-in security principals: “NT AUTHORITY\NETWORK SERVICE”, “NT AUTHORITY\LOCAL SERVICE”, “Built-In\Administrators”. This helps to prevent non-admin users on the same machine “leaking” Syncthing’s secure device keys and API key from the config.
  • Added MSI properties to “do your own Syncthing”, offering ability to use MSI command line switches for personalization and being to able to create MSI Transforms (.MST) with MS Orca.

Valid switches for the MSI / Transform are:

		<!-- App specific properties -->
		<!-- Leave ADD_DEVICE_HOST at the pre-defined value if you do not need to enroll a new device -->
		<Property Id='ADD_DEVICE_HOST' Value='localhost.localdomain' />
		<Property Id='ADD_DEVICE_ID' Value='CF6WMOG-F4RHVKW-2FTJONJ-GJ3FZQS-YW5TJVW-VDDT6ZQ-EVJ2WDP-RL4QZQO' />
		<Property Id='ADD_DEVICE_PORT' Value='22000' />
		<Property Id='crashReportingEnabled' Value='false' />
		<Property Id='DATA_PORT' Value='22000' />
		<Property Id='globalAnnounceEnabled' Value='true' />
		<Property Id='hashers' Value='0' />
		<Property Id='localAnnounceEnabled' Value='true' />
		<Property Id='natEnabled' Value='true' />
		<Property Id='OVERRIDE_DEVICE_NAME_WITH_COMPUTERNAME' Value='1' />
		<Property Id='OVERRIDE_EXISTING_CONFIG' Value='0' />
		<Property Id='relaysEnabled' Value='true' />
		<Property Id='REMOTE_WEB_UI' Value='0' />
		<!-- SERVICE_ACCOUNT options: LOCALSERVICE, NETWORKSERVICE, SYSTEM -->
		<Property Id='SERVICE_ACCOUNT' Value='LOCALSERVICE' />
		<Property Id='STNOUPGRADE' Value='1' />
		<Property Id='urAccepted' Value='-1' />
		<Property Id='WEB_UI_PORT' Value='8384' />
2 Likes

Neat

1 Like

thanks for sharing, I’m sure many admins will find this helpful!

1 Like