Simplify Syncthing Installation with This Bash Script
Setting up Syncthing on a Debian-based system can be time-consuming. Fortunately, I crafted a handy Bash script that automates the entire process, making synchronization effortless.
What is Syncthing?
Syncthing is an open-source tool for secure, decentralized file synchronization across multiple devices. It ensures your data remains private and under your control without relying on third-party servers.
Overview of the Setup Script
The provided script automates the installation and configuration of Syncthing. Here’s a brief breakdown:
Key Features
- 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 the new user and handles service restarts.
- Status Check: Retrieves and displays the Syncthing status, including API keys and device information.
Bash
#!/bin/bash
# =========================================
# Syncthing Setup
# =========================================
#
# Version: 1.0.4
# Script written by Warith Al Maawali
#
# Discord channel: https://discord.gg/KEFErEx
# Twitter: http://twitter.com/warith2020
# Linkedin: http://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"
syncthing -generate="~/.config/syncthing"
# Ensure CONFIG_FILE exists, create if missing
if [ ! -f "$CONFIG_FILE" ]; then
syncthing generate
syncthing -generate="~/.config/syncthing"
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 http://<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 '.[] | "Device ID: \(.deviceID), IP: \(.addresses[])"'
echo "Active Devices:"
echo "$ACTIVE_DEVICES" | jq -r '.[] | "Device ID: \(.deviceID), IP: \(.addresses[])"'
echo "Pending Folders:"
echo "$PENDING_FOLDERS" | jq -r '.[] | "Folder ID: \(.folderID), Folder Name: \(.folderName)"'
}
# Main script execution
setup_syncthing
show_syncthing_status
Bash
Posted in Tech Blog