My attempt at CLI-Based onboarding of new clients, with auto-accepting of folders.

I know this has been done a million times, but I got it working for 2 test clients and I wanted to share as it has taken me some effort to get this all in 1 place. Maybe this isn’t that applicable, but for me it is. My environment has the following:

  1. About 30 linux VM’s and clients
  2. One “Primary” syncthing device, which is my introducer. We need that device’s ID, and the ability to ssh into it.
    1. Device ID stylized as AAAAAAA-BBBBBBB-CCCCCCC-DDDDDDD-EEEEEEE-FFFFFFF-GGGGGGG-HHHHHHH, make sure to replace
    2. Introducer hostname stylized by INTRODUCER-HOSTNAME, make sure to replace
    3. If you use an alt port, change it from 22
  3. Optionally, a list of shares we want everyone in the group to have; you can also enumerate them for automatic adding, my examples are below:
    1. ~/.dotfiles called .dotfiles
    2. ~/.scripts called .scripts

First I do some first-run things by launching syncthing, killing it, then using sed to set some configs, this is optional. I also create my directories here, which you can modify as needed. I create the user service as well. I’m doing this all as root, and for this example, we’re using the user account “surfrock66” but you can modify that as needed. This shouldn’t be copied and pasted, but used to adapt your personal onboarding script.

mkdir /var/syncthing
chown syncthing:syncthing /var/syncthing
sudo -u surfrock66 syncthing &
sleep 10
killall syncthing
sed -i 's|127.0.0.1|0.0.0.0|g' /home/surfrock66/.local/state/syncthing/config.xml
sed -i 's|<theme>default</theme>|<theme>dark</theme>|g' /home/surfrock66/.local/state/syncthing/config.xml
sed -i 's|<gui enabled="true" tls="false"|<gui enabled="true" tls="true"|g' /home/surfrock66/.local/state/syncthing/config.xml
systemctl enable syncthing@surfrock66.service
systemctl start syncthing@surfrock66.service
mkdir /home/surfrock66/.scripts
chown surfrock66:surfrock66 /home/surfrock66/.scripts
chmod 775 /home/surfrock66/.scripts
mkdir /home/surfrock66/.dotfiles
chown surfrock66:surfrock66 /home/surfrock66/.dotfiles
chmod 775 /home/surfrock66/.dotfiles
ufw allow 8384
ufw allow 22000
exit

Now I will be acting as my normal user account, where I’ll be doing the actual syncthing onboarding. Here is where we need the ID of the introducer, the password for the webgui we want to use (I redacted it), and the ssh credentials for the introducer.

syncthing cli config gui user set USERNAME
syncthing cli config gui password set PASSWORD
syncthing cli config options urseen set 1
syncthing cli config options uraccepted set -- -1
syncthing cli config devices add --device-id AAAAAAA-BBBBBBB-CCCCCCC-DDDDDDD-EEEEEEE-FFFFFFF-GGGGGGG-HHHHHHH --introducer --auto-accept-folders
myID=$(syncthing cli show system | grep "myID" | sed "s|  \"myID\": \"||g" | sed "s|\",||g")
syncthing cli config devices AAAAAAA-BBBBBBB-CCCCCCC-DDDDDDD-EEEEEEE-FFFFFFF-GGGGGGG-HHHHHHH auto-accept-folders set true

# Accept the new device over ssh
ssh INTRODUCER-HOSTNAME -p 22 syncthing cli config devices add --device-id $myID


####
# Choose 1 of the following 2, one if you want to automatically enumerate all 
#  non-default folders and initiate the sharing, the other if you want to list 
#  them individually/manually
####

folders=$(ssh INTRODUCER-HOSTNAME -p 22 syncthing cli config folders list); for folder in $folders; do if [ "$folder" != "default" ]; then ssh INTRODUCER-HOSTNAME -p 22 syncthing cli config folders "$folder" devices add --device-id $myID; fi; done

# You need 1 entry for each share you wish to share
ssh INTRODUCER-HOSTNAME -p 22 syncthing cli config folders ".dotfiles" devices add --device-id $myID
ssh INTRODUCER-HOSTNAME -p 22 syncthing cli config folders ".scripts" devices add --device-id $myID


####
# Choose 1 of the following 2, one if you want to silently accept, the other 
#  if you want some output for sanity checking
####

# Silently accept all pending connections
stkid=$(syncthing cli show pending devices | jq '. | keys | .[]'); for id in $stkid; do cleanid=$(echo $id | tr -d '"'); syncthing cli config devices add --device-id $cleanid; done

# List and accept all pending connections
st_pending_conn_id=$(syncthing cli show pending devices | jq '. | keys | .[]'); for id in $st_pending_conn_id; do cleanid=$(echo $id | tr -d '"'); echo $cleanid; conn_ip=$(syncthing cli show pending devices | jq --arg CLEANID "$cleanid" '.connections | "\(.[$CLEANID] | .address)"'); cleanip=$(echo $conn_ip | tr -d '"' | cut -d : -f 1); dig -x $cleanip +short PTR; syncthing cli config devices add --device-id $cleanid; done


####
# Choose 1 of the following 2, one if you want to try to auto-create shares, 
#  the other if you want to do each manually
####

# Automatically create folders for all pending folders
st_pending_folders=$(syncthing cli show pending folders | jq '. | keys .[]'); for folders in $st_pending_folders; do cleanfolder=$(echo $folders | tr -d '"'); echo $cleanfolder; syncthing cli config folders add --id "$cleanfolder" --label "$cleanfolder" --path "~/$cleanfolder"; done

syncthing cli config folders add --id ".dotfiles" --label ".dotfiles" --path "~/.dotfiles"
syncthing cli config folders add --id ".scripts" --label ".scripts" --path "~/.scripts"


# Restart syncthing for this to take effect
syncthing cli operations restart

If a client isn’t online when you do this you may have to repeat the accept steps, but if you do the automatic ones, that’s pretty simple. I would love some feedback; I tested this onboarding 2 clients into the ecosystem and it worked, but I don’t know if I consider it “tested” yet.

I didn’t check all of your script code. Just what springs out is the starting and killing Syncthing after 10 seconds. I assume your goal is to let it create a configuration file and certificate. That’s where the syncthing generate command may prove useful to you:

It allows setting the GUI credentials right away. Just the GUI listen address is not available there as an option, but I would recommend changing that via syncthing cli config, as well as the other options. It’s no problem as long as you are still running the command on the same host. You already found the operation to restart Syncthing via its cli, use that to apply the changed address.

So you should not need any sed scripting at all, which is usually fragile compared to the built-in cli subcommands. You don’t even need to worry about the config file location. And the device ID an be easily extracted from the output of syncthing generate.

Hope that helps, based on my own experience with semi-automatic provisioning of Syncthing devices.

1 Like