Hold Tight...

0 %
Driving cybersecurity excellence
Innovator behind Kodachi OS
  • Residence:
    ::0
  • Uptime Binary:
    110001
  • Mantra:
    Innovate, Secure, Repeat
ONS
EEDS
NSSG
Cybersecurity
Programming & R&D
Cryptocurrency
AI & vibe coding
  • Bash
  • Gambas
  • Delphi
  • PHP
  • Visual Basic
  • Rust

Effortless File Syncing: Automate Syncthing Installation with This Script

03/11/2024
3 min readDeep Tech4 code examplesUpdated October 2026

Key points

  • A Bash script that installs Syncthing, creates a dedicated low-privileged user, sets up its folders and service, and prints the status and API key.
  • The script now creates the configuration with syncthing generate, the form Syncthing 2 (August 2025) requires, and sets the GUI login from GUI_USER and GUI_PASSWORD.
  • The script expects your own config.xml beside it; without one, the GUI listens on 127.0.0.1:8384.

Simplify Syncthing Installation with This Bash Script

Updated October 2026: Syncthing 2.0 came out in August 2025 (2.1.6 is current), and the official repository at apt.syncthing.net carries it. Read these points before you run the Syncthing setup script:

  • It copies a config.xml from the folder you run it in, and that file is not part of this post: the GUI user and password at the top of the script are applied by syncthing generate, but the addresses are only printed, not applied. Without your own config.xml, Syncthing creates a default one with the GUI on 127.0.0.1:8384, not on port 5612.
  • Syncthing 2 no longer accepts single-dash options, so the script’s two syncthing -generate lines failed (and the quoted ~ in them was never expanded). The script below now runs this line instead, which also sets the GUI login from GUI_USER and GUI_PASSWORD:
  • Remove the net.ipv4.ip_unprivileged_port_start=0 line the script adds to /etc/sysctl.conf: it lets every local user open ports below 1024, and ports 5612 and 22222 do not need it. sysctl -w net.ipv4.ip_unprivileged_port_start=1024 restores the default.
  • Running the script again deletes /home/syncthing/.config/syncthing, including the device keys, so the server gets a new device ID.
  • The status check needs jq (apt install jq), and the service starts on boot only after systemctl enable syncthing@syncthing.
sudo -u syncthing syncthing generate --home=/home/syncthing/.config/syncthing --gui-user="$GUI_USER" --gui-password="$GUI_PASSWORD"

Setting up Syncthing on a Debian-based system can be time-consuming. This Bash script automates the entire process, making secure file synchronization effortless and efficient.

What Is Syncthing?

Syncthing is an open-source tool for secure, decentralized file synchronization across multiple devices. It keeps your data private and under your control, avoiding reliance on third-party servers.

Key Features of the Script

  • Root Privileges Check: Ensures the script runs with necessary permissions.
  • User Management: Creates a dedicated Syncthing user for enhanced security.
  • Installation: Installs Syncthing if it’s not already present.
  • Configuration: Sets up configuration directories, permissions, and necessary services.
  • Service Management: Configures Syncthing to run under a low-privileged user and manages service restarts.
  • Status Check: Retrieves and displays Syncthing status, API keys, and connected devices.

How It Works

  1. Prepares the System:
    • Removes any previous Syncthing configurations.
    • Creates a dedicated syncthing user to enhance security.
  2. Installs Syncthing: Installs Syncthing from Debian repositories if it is not already present.
  3. Configures Syncthing:
    • Sets up configuration files, directories, and permissions.
    • Copies your own config.xml (from the folder you run the script in) with your GUI and networking settings.
  4. Manages the Service:
    • Disables root-level services and ensures Syncthing runs under the correct user.
    • Restarts the service to apply changes. To start it on boot, run systemctl enable syncthing@syncthing.
  5. Displays Status and Next Steps:
    • Outputs API keys, GUI credentials, and connection details.
    • Provides instructions for pairing devices and managing shared folders.

Quick Start with the Syncthing Setup Script

  1. Save and Make Executable: copy the full script at the end of this post into a file named syncthing-setup.sh, put your config.xml in the same folder, then run:
   chmod +x syncthing-setup.sh
  1. Run the Script:
   sudo ./syncthing-setup.sh
  1. Let It Run: Let the script install Syncthing, copy your configuration and set up the service.
  1. Access Syncthing:
    • Open the web interface at http://<your-server-ip>:5612.
    • Use the provided credentials to log in and configure synchronization.

Benefits

  • Time-Saving: Automates the installation and configuration process.
  • Enhanced Security: Runs Syncthing under a dedicated user with restricted permissions.
  • Decentralized Control: Ensures your data remains private and accessible only to authorized devices.
  • Ease of Use: Simplifies complex configurations with a streamlined script.

Conclusion

This Bash script makes setting up Syncthing on Debian-based systems a breeze. By automating every step, it ensures a secure and efficient synchronization setup. Take control of your data and simplify file sharing across devices today with this powerful tool! For one-way, real-time sync between servers, see my Lsyncd setup script.

ShellScript
#!/bin/bash
# =========================================
# Syncthing Setup
# =========================================
#
# Version: 1.0.4
# Script written by Warith AL Maawali
#
# Discord channel: https://discord.gg/KEFErEx
# Twitter: https://x.com/warith2020
# Linkedin: https://www.linkedin.com/in/warith1977
# Website: https://www.digi77.com
# (c) 2024
#
# Description:
# This script installs and configures Syncthing on a Debian-based system.
# It ensures root privileges, removes old configurations, creates a Syncthing user,
# installs Syncthing if not already installed, prepares the configuration directory,
# and sets up necessary permissions and services.
#
# This software is dual-licensed:
#
# Personal, non-commercial use: Apache License 2.0
# Commercial, corporate, or organizational use: Separate commercial license required. 
# Contact me for licensing inquiries.
#
# Usage: ./syncthing-setup.sh
#
# Usage Examples:
#   Run this script as root to set up Syncthing:
#     ./syncthing-setup.sh
# =========================================

# Global Variables
FOLDER_PATH="/var/www/html/vps-cards"
GUI_USER="x_your_username_x"
GUI_PASSWORD='x_your_password_x'
ENCRYPTION_PASSWORD="x_your_password_x"
GUI_ADDRESS="0.0.0.0:5612"
LISTEN_TCP="tcp://0.0.0.0:22222"
LISTEN_TCP6="tcp6://[::]:22222"
LISTEN_QUIC="quic://0.0.0.0:22222"
LISTEN_QUIC6="quic6://[::]:22221"

# Configuration File Path
CONFIG_DIR="/home/syncthing/.config/syncthing"
CONFIG_FILE="$CONFIG_DIR/config.xml"
USER="syncthing"

# Function to install and configure Syncthing on Debian
setup_syncthing() {
  # Ensure root privileges
  if [ "$EUID" -ne 0 ]; then
    echo "Please run as root"
    exit 1
  fi

  # Remove old configuration directory
  rm -rf "$CONFIG_DIR"

  # Create Syncthing user if it doesn't exist
  if ! id -u $USER &>/dev/null; then
    useradd -r -m -d /home/syncthing -s /usr/sbin/nologin $USER
    echo "User $USER created."
  fi

  # Install Syncthing if not already installed
  if ! command -v syncthing &>/dev/null; then
    apt update && apt install -y syncthing
  fi

  # Prepare the configuration directory and permissions
  mkdir -p "$CONFIG_DIR"
  chown -R $USER:$USER "$CONFIG_DIR"

  # Disable root service for Syncthing and configure for $USER
  systemctl stop syncthing@root && systemctl disable syncthing@root && systemctl mask syncthing@root
  systemctl stop syncthing@$USER
  setcap 'cap_net_bind_service=+ep' /usr/bin/syncthing

  # Ensure low privileged port binding is allowed
  if ! grep -q 'net.ipv4.ip_unprivileged_port_start=0' /etc/sysctl.conf; then
    echo 'net.ipv4.ip_unprivileged_port_start=0' | sudo tee -a /etc/sysctl.conf && sysctl -p
  fi

  # Start Syncthing service for user
  systemctl restart syncthing@$USER

  # Copy the provided config.xml to the Syncthing configuration directory
  cp -f config.xml "$CONFIG_FILE"
  chown $USER:$USER "$CONFIG_FILE"
  sudo -u "$USER" syncthing generate --home="$CONFIG_DIR" --gui-user="$GUI_USER" --gui-password="$GUI_PASSWORD"
  # Ensure CONFIG_FILE exists, create if missing
  if [ ! -f "$CONFIG_FILE" ]; then
    sudo -u "$USER" syncthing generate --home="$CONFIG_DIR" --gui-user="$GUI_USER" --gui-password="$GUI_PASSWORD"
    while [ ! -f "$CONFIG_FILE" ]; do sleep 1; done
  fi

  # Final restart to apply configurations
  systemctl restart syncthing@$USER

  # Display next steps
  echo "====================================================="
  echo "Syncthing is configured. Access the web interface at https://<your-vps-ip>:${GUI_ADDRESS##*:}"
  echo "The configuration file has been copied. You might want to change those values later."
  echo "Current configuration values:"
  echo "FOLDER_PATH: $FOLDER_PATH"
  echo "GUI_USER: $GUI_USER"
  echo "GUI_PASSWORD: $GUI_PASSWORD"
  echo "ENCRYPTION_PASSWORD: $ENCRYPTION_PASSWORD"
  echo "GUI_ADDRESS: $GUI_ADDRESS"
  echo "LISTEN_TCP: $LISTEN_TCP"
  echo "LISTEN_TCP6: $LISTEN_TCP6"
  echo "LISTEN_QUIC: $LISTEN_QUIC"
  echo "LISTEN_QUIC6: $LISTEN_QUIC6"
  echo "Next steps:"
  echo "1. Pair this device with others via the Syncthing web interface."
  echo "2. Configure shared folders on other nodes and approve sync requests."
  echo "3. Path to configuration file: $CONFIG_FILE"
  echo "====================================================="
}

# Function to show Syncthing status
show_syncthing_status() {
  # Check if xmlstarlet is installed, if not, install it
  if ! command -v xmlstarlet &>/dev/null; then
    echo "xmlstarlet not found, installing..."
    sudo apt-get update && sudo apt-get install -y xmlstarlet
  fi

  # Extract API key from the Syncthing config
  API_KEY=$(xmlstarlet sel -t -v "//apikey" "$CONFIG_FILE")
  if [ -z "$API_KEY" ]; then
    echo "API key not found in the Syncthing config."
    exit 1
  fi
  echo "API Key: $API_KEY"
  # Set your Syncthing API key and base URL
  BASE_URL="https://localhost:5612"
  FOLDER_ID="unvv4-ddta3" # Replace with your actual folder ID

  # Get the list of pending folders and devices
  PENDING_FOLDERS=$(curl -k -s -X GET -H "X-API-Key: $API_KEY" "$BASE_URL/rest/cluster/pending/folders")
  PENDING_DEVICES=$(curl -k -s -X GET -H "X-API-Key: $API_KEY" "$BASE_URL/rest/cluster/pending/devices")
  ACTIVE_DEVICES=$(curl -k -s -X GET -H "X-API-Key: $API_KEY" "$BASE_URL/rest/config/devices")

  # Extract and show only device id and ip for active and pending devices
  echo "Pending Devices:"
  echo "$PENDING_DEVICES" | jq -r 'to_entries[] | "Device ID: \(.key), IP: \(.value.address)"'

  echo "Active Devices:"
  echo "$ACTIVE_DEVICES" | jq -r '.[] | "Device ID: \(.deviceID), IP: \(.addresses[])"'

  echo "Pending Folders:"
  echo "$PENDING_FOLDERS" | jq -r 'to_entries[] | "Folder ID: \(.key), Folder Name: \([.value.offeredBy[].label] | first)"'
}

# Main script execution
setup_syncthing
show_syncthing_status
ShellScript
Posted in Deep TechTags: