{"id":1892,"date":"2025-07-23T09:18:09","date_gmt":"2025-07-23T16:18:09","guid":{"rendered":"https:\/\/surfrock66.com\/?p=1892"},"modified":"2025-07-23T09:18:09","modified_gmt":"2025-07-23T16:18:09","slug":"my-attempt-at-cli-based-onboarding-of-new-syncthing-clients-with-auto-accepting-of-folders","status":"publish","type":"post","link":"https:\/\/surfrock66.com\/?p=1892","title":{"rendered":"My attempt at CLI-Based onboarding of new syncthing clients, with auto-accepting of folders."},"content":{"rendered":"<p>This was originally posted here, but I'm keeping a local copy for self-reliance and preservation: <a href=\"https:\/\/forum.syncthing.net\/t\/my-attempt-at-cli-based-onboarding-of-new-clients-with-auto-accepting-of-folders\/24632\/1\" title=\"https:\/\/forum.syncthing.net\/t\/my-attempt-at-cli-based-onboarding-of-new-clients-with-auto-accepting-of-folders\/24632\/1\">https:\/\/forum.syncthing.net\/t\/my-attempt-at-cli-based-onboarding-of-new-clients-with-auto-accepting-of-folders\/24632\/1<\/a><\/p>\n<p>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\u2019t that applicable, but for me it is. My environment has the following:<\/p>\n<ol>\n<li>About 30 linux VM\u2019s and clients<\/li>\n<li>One \u201cPrimary\u201d syncthing device, which is my introducer. We need that device\u2019s ID, and the ability to ssh into it.\n<ol>\n<li>Device ID stylized as AAAAAAA-BBBBBBB-CCCCCCC-DDDDDDD-EEEEEEE-FFFFFFF-GGGGGGG-HHHHHHH, make sure to replace<\/li>\n<li>Introducer hostname stylized by INTRODUCER-HOSTNAME, make sure to replace<\/li>\n<li>If you use an alt port, change it from 22<\/li>\n<\/ol>\n<\/li>\n<li>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:\n<ol>\n<li>~\/.dotfiles called .dotfiles<\/li>\n<li>~\/.scripts called .scripts<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p><!--more--><\/p>\n<p>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\u2019m doing this all as root, and for this example, we\u2019re using the user account \u201csurfrock66\u201d but you can modify that as needed. This shouldn\u2019t be copied and pasted, but used to adapt your personal onboarding script.<\/p>\n<pre><code>mkdir \/var\/syncthing\nchown syncthing:syncthing \/var\/syncthing\nsudo -u surfrock66 syncthing &amp;\nsleep 10\nkillall syncthing\nsed -i &#039;s|127.0.0.1|0.0.0.0|g&#039; \/home\/surfrock66\/.local\/state\/syncthing\/config.xml\nsed -i &#039;s|&lt;theme&gt;default&lt;\/theme&gt;|&lt;theme&gt;dark&lt;\/theme&gt;|g&#039; \/home\/surfrock66\/.local\/state\/syncthing\/config.xml\nsed -i &#039;s|&lt;gui enabled=&quot;true&quot; tls=&quot;false&quot;|&lt;gui enabled=&quot;true&quot; tls=&quot;true&quot;|g&#039; \/home\/surfrock66\/.local\/state\/syncthing\/config.xml\nsystemctl enable syncthing@surfrock66.service\nsystemctl start syncthing@surfrock66.service\nmkdir \/home\/surfrock66\/.scripts\nchown surfrock66:surfrock66 \/home\/surfrock66\/.scripts\nchmod 775 \/home\/surfrock66\/.scripts\nmkdir \/home\/surfrock66\/.dotfiles\nchown surfrock66:surfrock66 \/home\/surfrock66\/.dotfiles\nchmod 775 \/home\/surfrock66\/.dotfiles\nufw allow 8384\nufw allow 22000\nexit<\/code><\/pre>\n<p>Now I will be acting as my normal user account, where I\u2019ll 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.<\/p>\n<pre><code>syncthing cli config gui user set USERNAME\nsyncthing cli config gui password set PASSWORD\nsyncthing cli config options urseen set 1\nsyncthing cli config options uraccepted set -- -1\nsyncthing cli config devices add --device-id AAAAAAA-BBBBBBB-CCCCCCC-DDDDDDD-EEEEEEE-FFFFFFF-GGGGGGG-HHHHHHH --introducer --auto-accept-folders\nmyID=$(syncthing cli show system | grep &quot;myID&quot; | sed &quot;s|  \\&quot;myID\\&quot;: \\&quot;||g&quot; | sed &quot;s|\\&quot;,||g&quot;)\nsyncthing cli config devices AAAAAAA-BBBBBBB-CCCCCCC-DDDDDDD-EEEEEEE-FFFFFFF-GGGGGGG-HHHHHHH auto-accept-folders set true\n\n# Accept the new device over ssh\nssh INTRODUCER-HOSTNAME -p 22 syncthing cli config devices add --device-id $myID\n\n####\n# Choose 1 of the following 2, one if you want to automatically enumerate all \n#  non-default folders and initiate the sharing, the other if you want to list \n#  them individually\/manually\n####\n\nfolders=$(ssh INTRODUCER-HOSTNAME -p 22 syncthing cli config folders list); for folder in $folders; do if [ &quot;$folder&quot; != &quot;default&quot; ]; then ssh INTRODUCER-HOSTNAME -p 22 syncthing cli config folders &quot;$folder&quot; devices add --device-id $myID; fi; done\n\n# You need 1 entry for each share you wish to share\nssh INTRODUCER-HOSTNAME -p 22 syncthing cli config folders &quot;.dotfiles&quot; devices add --device-id $myID\nssh INTRODUCER-HOSTNAME -p 22 syncthing cli config folders &quot;.scripts&quot; devices add --device-id $myID\n\n####\n# Choose 1 of the following 2, one if you want to silently accept, the other \n#  if you want some output for sanity checking\n####\n\n# Silently accept all pending connections\nstkid=$(syncthing cli show pending devices | jq &#039;. | keys | .[]&#039;); for id in $stkid; do cleanid=$(echo $id | tr -d &#039;&quot;&#039;); syncthing cli config devices add --device-id $cleanid; done\n\n# List and accept all pending connections\nst_pending_conn_id=$(syncthing cli show pending devices | jq &#039;. | keys | .[]&#039;); for id in $st_pending_conn_id; do cleanid=$(echo $id | tr -d &#039;&quot;&#039;); echo $cleanid; conn_ip=$(syncthing cli show pending devices | jq --arg CLEANID &quot;$cleanid&quot; &#039;.connections | &quot;\\(.[$CLEANID] | .address)&quot;&#039;); cleanip=$(echo $conn_ip | tr -d &#039;&quot;&#039; | cut -d : -f 1); dig -x $cleanip +short PTR; syncthing cli config devices add --device-id $cleanid; done\n\n####\n# Choose 1 of the following 2, one if you want to try to auto-create shares, \n#  the other if you want to do each manually\n####\n\n# Automatically create folders for all pending folders\nst_pending_folders=$(syncthing cli show pending folders | jq &#039;. | keys .[]&#039;); for folders in $st_pending_folders; do cleanfolder=$(echo $folders | tr -d &#039;&quot;&#039;); echo $cleanfolder; syncthing cli config folders add --id &quot;$cleanfolder&quot; --label &quot;$cleanfolder&quot; --path &quot;~\/$cleanfolder&quot;; done\n\nsyncthing cli config folders add --id &quot;.dotfiles&quot; --label &quot;.dotfiles&quot; --path &quot;~\/.dotfiles&quot;\nsyncthing cli config folders add --id &quot;.scripts&quot; --label &quot;.scripts&quot; --path &quot;~\/.scripts&quot;\n\n# Restart syncthing for this to take effect\nsyncthing cli operations restart<\/code><\/pre>\n<p>If a client isn\u2019t online when you do this you may have to repeat the accept steps, but if you do the automatic ones, that\u2019s pretty simple. I would love some feedback; I tested this onboarding 2 clients into the ecosystem and it worked, but I don\u2019t know if I consider it \u201ctested\u201d yet.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This was originally posted here, but I&#8217;m keeping a local copy for self-reliance and preservation: https:\/\/forum.syncthing.net\/t\/my-attempt-at-cli-based-onboarding-of-new-clients-with-auto-accepting-of-folders\/24632\/1 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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,3,7],"tags":[],"class_list":["post-1892","post","type-post","status-publish","format-standard","hentry","category-geek","category-projects","category-random"],"_links":{"self":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts\/1892","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1892"}],"version-history":[{"count":3,"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts\/1892\/revisions"}],"predecessor-version":[{"id":1895,"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts\/1892\/revisions\/1895"}],"wp:attachment":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1892"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1892"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1892"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}