13 KiB
Installation Guide
Complete step-by-step tutorial for setting up Tailscale SSH Sync Agent.
Table of Contents
- Prerequisites
- Step 1: Install Tailscale
- Step 2: Install sshsync
- Step 3: Configure SSH
- Step 4: Configure sshsync Groups
- Step 5: Install Agent
- Step 6: Test Installation
- Troubleshooting
Prerequisites
Before you begin, ensure you have:
- Operating System: macOS, Linux, or BSD
- Python: Version 3.10 or higher
- pip: Python package installer
- Claude Code: Installed and running
- Remote machines: At least one machine you want to manage
- SSH access: Ability to SSH to remote machines
Check Python version:
python3 --version
# Should show: Python 3.10.x or higher
Check pip:
pip3 --version
# Should show: pip xx.x.x from ...
Step 1: Install Tailscale
Tailscale provides secure networking between your machines.
macOS
# Install via Homebrew
brew install tailscale
# Start Tailscale
sudo tailscale up
# Follow authentication link in terminal
# This will open browser to log in
Linux (Ubuntu/Debian)
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
# Start and authenticate
sudo tailscale up
# Follow authentication link
Linux (Fedora/RHEL)
# Add repository
sudo dnf config-manager --add-repo https://pkgs.tailscale.com/stable/fedora/tailscale.repo
# Install
sudo dnf install tailscale
# Enable and start
sudo systemctl enable --now tailscaled
sudo tailscale up
Verify Installation
# Check Tailscale status
tailscale status
# Should show list of machines in your tailnet
# Example output:
# 100.64.1.10 homelab-1 user@ linux -
# 100.64.1.11 laptop user@ macOS -
Important: Install and authenticate Tailscale on all machines you want to manage.
Step 2: Install sshsync
sshsync is the CLI tool for managing SSH operations across multiple hosts.
# Install via pip
pip3 install sshsync
# Or use pipx for isolated installation
pipx install sshsync
Verify Installation
# Check version
sshsync --version
# Should show: sshsync, version x.x.x
Common Installation Issues
Issue: pip3: command not found
Solution:
# macOS
brew install python3
# Linux (Ubuntu/Debian)
sudo apt install python3-pip
# Linux (Fedora/RHEL)
sudo dnf install python3-pip
Issue: Permission denied during install
Solution:
# Install for current user only
pip3 install --user sshsync
# Or use pipx
pip3 install --user pipx
pipx install sshsync
Step 3: Configure SSH
SSH configuration defines how to connect to each machine.
Step 3.1: Generate SSH Keys (if you don't have them)
# Generate ed25519 key (recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"
# Press Enter to use default location (~/.ssh/id_ed25519)
# Enter passphrase (or leave empty for no passphrase)
Output:
Your identification has been saved in /Users/you/.ssh/id_ed25519
Your public key has been saved in /Users/you/.ssh/id_ed25519.pub
Step 3.2: Copy Public Key to Remote Machines
For each remote machine:
# Copy SSH key to remote
ssh-copy-id user@machine-hostname
# Example:
ssh-copy-id admin@100.64.1.10
Manual method (if ssh-copy-id doesn't work):
# Display public key
cat ~/.ssh/id_ed25519.pub
# SSH to remote machine
ssh user@remote-host
# On remote machine:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "your-public-key-here" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
exit
Step 3.3: Test SSH Connection
# Test connection (should not ask for password)
ssh user@remote-host "hostname"
# If successful, should print remote hostname
Step 3.4: Create SSH Config File
Edit ~/.ssh/config:
vim ~/.ssh/config
Add host entries:
# Production servers
Host prod-web-01
HostName prod-web-01.tailnet.ts.net
User deploy
IdentityFile ~/.ssh/id_ed25519
Port 22
Host prod-web-02
HostName 100.64.1.21
User deploy
IdentityFile ~/.ssh/id_ed25519
Host prod-db-01
HostName 100.64.1.30
User deploy
IdentityFile ~/.ssh/id_ed25519
# Development
Host dev-laptop
HostName dev-laptop.tailnet.ts.net
User developer
IdentityFile ~/.ssh/id_ed25519
Host dev-desktop
HostName 100.64.1.40
User developer
IdentityFile ~/.ssh/id_ed25519
# Homelab
Host homelab-1
HostName 100.64.1.10
User admin
IdentityFile ~/.ssh/id_ed25519
Host homelab-2
HostName 100.64.1.11
User admin
IdentityFile ~/.ssh/id_ed25519
Important fields:
- Host: Alias you'll use (e.g., "homelab-1")
- HostName: Actual hostname or IP (Tailscale hostname or IP)
- User: SSH username on remote machine
- IdentityFile: Path to SSH private key
Step 3.5: Set Correct Permissions
# SSH config should be readable only by you
chmod 600 ~/.ssh/config
# SSH directory permissions
chmod 700 ~/.ssh
# Private key permissions
chmod 600 ~/.ssh/id_ed25519
# Public key permissions
chmod 644 ~/.ssh/id_ed25519.pub
Step 3.6: Verify All Hosts
Test each host in your config:
# Test each host
ssh homelab-1 "echo 'Connection successful'"
ssh prod-web-01 "echo 'Connection successful'"
ssh dev-laptop "echo 'Connection successful'"
# Should connect without asking for password
Step 4: Configure sshsync Groups
Groups organize your hosts for easy management.
Step 4.1: Initialize sshsync Configuration
# Sync hosts and create groups
sshsync sync
What this does:
- Reads all hosts from
~/.ssh/config - Prompts you to assign hosts to groups
- Creates
~/.config/sshsync/config.yaml
Step 4.2: Follow Interactive Prompts
Found 7 ungrouped hosts:
1. homelab-1
2. homelab-2
3. prod-web-01
4. prod-web-02
5. prod-db-01
6. dev-laptop
7. dev-desktop
Assign groups now? [Y/n]: Y
Enter group name for homelab-1 (or skip): homelab
Enter group name for homelab-2 (or skip): homelab
Enter group name for prod-web-01 (or skip): production,web
Enter group name for prod-web-02 (or skip): production,web
Enter group name for prod-db-01 (or skip): production,database
Enter group name for dev-laptop (or skip): development
Enter group name for dev-desktop (or skip): development
Tips:
- Hosts can belong to multiple groups (separate with commas)
- Use meaningful group names (production, development, web, database, homelab)
- Skip hosts you don't want to group yet
Step 4.3: Verify Configuration
# View generated config
cat ~/.config/sshsync/config.yaml
Expected output:
groups:
production:
- prod-web-01
- prod-web-02
- prod-db-01
web:
- prod-web-01
- prod-web-02
database:
- prod-db-01
development:
- dev-laptop
- dev-desktop
homelab:
- homelab-1
- homelab-2
Step 4.4: Test sshsync
# List hosts
sshsync ls
# List with status
sshsync ls --with-status
# Test command execution
sshsync all "hostname"
# Test group execution
sshsync group homelab "uptime"
Step 5: Install Agent
Step 5.1: Navigate to Agent Directory
cd /path/to/tailscale-sshsync-agent
Step 5.2: Verify Agent Structure
# List files
ls -la
# Should see:
# .claude-plugin/
# scripts/
# tests/
# references/
# SKILL.md
# README.md
# VERSION
# CHANGELOG.md
# etc.
Step 5.3: Validate marketplace.json
# Check JSON is valid
python3 -c "import json; json.load(open('.claude-plugin/marketplace.json')); print('✅ Valid JSON')"
# Should output: ✅ Valid JSON
Step 5.4: Install via Claude Code
In Claude Code:
/plugin marketplace add /absolute/path/to/tailscale-sshsync-agent
Example:
/plugin marketplace add /Users/you/tailscale-sshsync-agent
Expected output:
✓ Plugin installed successfully
✓ Skill: tailscale-sshsync-agent
✓ Description: Manages distributed workloads and file sharing...
Step 5.5: Verify Installation
In Claude Code:
"Which of my machines are online?"
Expected response: Agent should activate and check your Tailscale network.
Step 6: Test Installation
Test 1: Host Status
Query:
"Which of my machines are online?"
Expected: List of hosts with online/offline status
Test 2: List Groups
Query:
"What groups do I have configured?"
Expected: List of your sshsync groups
Test 3: Execute Command
Query:
"Check disk space on homelab machines"
Expected: Disk usage for hosts in homelab group
Test 4: Dry-Run
Query:
"Show me what would happen if I ran 'uptime' on all machines (dry-run)"
Expected: Preview without execution
Test 5: Run Test Suite
cd /path/to/tailscale-sshsync-agent
# Run all tests
python3 tests/test_integration.py
# Should show:
# Results: 11/11 passed
# 🎉 All tests passed!
Troubleshooting
Agent Not Activating
Symptoms: Agent doesn't respond to queries about machines/hosts
Solutions:
-
Check installation:
/plugin listShould show
tailscale-sshsync-agentin list. -
Reinstall:
/plugin remove tailscale-sshsync-agent /plugin marketplace add /path/to/tailscale-sshsync-agent -
Check marketplace.json:
cat .claude-plugin/marketplace.json # Verify "description" field matches SKILL.md frontmatter
SSH Connection Fails
Symptoms: "Permission denied" or "Connection refused"
Solutions:
-
Check SSH key:
ssh-add -l # Should list your SSH keyIf not listed:
ssh-add ~/.ssh/id_ed25519 -
Test SSH directly:
ssh -v hostname # -v shows verbose debug info -
Verify authorized_keys on remote:
ssh hostname "cat ~/.ssh/authorized_keys" # Should contain your public key
Tailscale Connection Issues
Symptoms: Hosts show as offline in Tailscale
Solutions:
-
Check Tailscale status:
tailscale status -
Restart Tailscale:
# macOS brew services restart tailscale # Linux sudo systemctl restart tailscaled -
Re-authenticate:
sudo tailscale up
sshsync Errors
Symptoms: "sshsync: command not found"
Solutions:
-
Reinstall sshsync:
pip3 install --upgrade sshsync -
Check PATH:
which sshsync # Should show path to sshsyncIf not found, add to PATH:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrc
Config File Issues
Symptoms: "Group not found" or "Host not found"
Solutions:
-
Verify SSH config:
cat ~/.ssh/config # Check host aliases are correct -
Verify sshsync config:
cat ~/.config/sshsync/config.yaml # Check groups are defined -
Re-sync:
sshsync sync
Test Failures
Symptoms: Tests fail with errors
Solutions:
-
Check dependencies:
pip3 list | grep -E "sshsync|pyyaml" -
Check Python version:
python3 --version # Must be 3.10+ -
Run tests individually:
python3 tests/test_helpers.py python3 tests/test_validation.py python3 tests/test_integration.py
Post-Installation
Recommended Next Steps
-
Create more groups for better organization:
sshsync gadd staging sshsync gadd backup-servers -
Test file operations:
"Push test file to homelab machines (dry-run)" -
Set up automation:
- Create scripts for common tasks
- Schedule backups
- Automate deployments
-
Review documentation:
- Read
references/sshsync-guide.mdfor advanced sshsync usage - Read
references/tailscale-integration.mdfor Tailscale tips
- Read
Security Checklist
- ✅ SSH keys are password-protected
- ✅ SSH config has correct permissions (600)
- ✅ Private keys have correct permissions (600)
- ✅ Tailscale ACLs configured (if using teams)
- ✅ Only necessary hosts have SSH access
- ✅ Regularly review connected devices in Tailscale
Summary
You now have:
- ✅ Tailscale installed and connected
- ✅ sshsync installed and configured
- ✅ SSH keys set up on all machines
- ✅ SSH config with all hosts
- ✅ sshsync groups organized
- ✅ Agent installed in Claude Code
- ✅ Tests passing
Start using:
"Which machines are online?"
"Run this on the least loaded machine"
"Push files to production servers"
"Deploy to staging then production"
For more examples, see README.md and SKILL.md.
Support
If you encounter issues:
- Check this troubleshooting section
- Review references/ for detailed guides
- Check DECISIONS.md for architecture rationale
- Run tests to verify installation
Happy automating! 🚀