Setting Up Passwordless SSH Across All Machines in Your Tailscale Network

Introduction

If you have multiple machines connected through Tailscale, you’ve probably found yourself typing SSH passwords repeatedly when jumping between systems. In this guide, I’ll show you how to set up passwordless SSH authentication across all your Tailscale machines, creating a seamless mesh network where any machine can connect to any other without passwords.

What You’ll Achieve

By the end of this guide, you’ll have:

  • Passwordless SSH authentication between all machines
  • Easy-to-remember SSH aliases (e.g., ssh laptopssh server)
  • A fully connected mesh network where every machine can reach every other machine
  • Works across different operating systems (Windows, Linux, macOS)

Prerequisites

  • Tailscale installed and running on all machines
  • SSH server enabled on all machines
  • Basic command line knowledge
  • Administrator/sudo access on all machines

Overview of the Process

For each machine, we’ll:

  1. Generate SSH keys without passphrases
  2. Distribute public keys to all other machines
  3. Create SSH config files for easy connections
  4. Test the connections

Step 1: Enable SSH Server

On Windows

# Check if SSH server is installed
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*'

# Install if needed (run as Administrator)
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

# Start and enable the service
Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'

# Verify it's running
Get-Service sshd

On Linux/macOS

# Ubuntu/Debian
sudo apt update
sudo apt install openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh

# macOS (usually pre-installed)
sudo systemsetup -setremotelogin on

Step 2: Get Tailscale IPs

List all your Tailscale machines and their IPs:

tailscale status

You’ll see output like:

100.x.x.1    laptop1        user@  linux    -
100.x.x.2    laptop2        user@  windows  -
100.x.x.3    server1        user@  linux    -
100.x.x.4    macmini        user@  darwin   -

Take note of the IPs and hostnames – you’ll need them later.

Step 3: Generate SSH Keys on Each Machine

Important: Generate keys WITHOUT a passphrase for passwordless authentication.

On Linux/macOS

# Generate key
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""

# View your public key
cat ~/.ssh/id_ed25519.pub

On Windows (PowerShell)

# Generate key
ssh-keygen -t ed25519 -f "$env:USERPROFILE\.ssh\id_ed25519" -N ""

# View your public key
Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub"

Save each machine’s public key – you’ll need to distribute them.

Step 4: Distribute Public Keys

For each machine, you need to add the public keys of ALL OTHER machines to its authorized_keys file.

On Linux/macOS

# Add a public key to authorized_keys
echo "ssh-ed25519 AAAA...rest-of-key... user@hostname" >> ~/.ssh/authorized_keys

# Set correct permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

On Windows (PowerShell)

For non-administrator users:

# Create .ssh directory if needed
mkdir "$env:USERPROFILE\.ssh" -Force

# Add public key
$key = "ssh-ed25519 AAAA...rest-of-key... user@hostname"
Add-Content -Path "$env:USERPROFILE\.ssh\authorized_keys" -Value $key

# Set permissions
icacls.exe "$env:USERPROFILE\.ssh\authorized_keys" /inheritance:r
icacls.exe "$env:USERPROFILE\.ssh\authorized_keys" /grant:r "$($env:USERNAME):(R)"
icacls.exe "$env:USERPROFILE\.ssh\authorized_keys" /grant:r "SYSTEM:(F)"

For administrator users (Windows treats them differently):

# Also add to administrators file
$key = "ssh-ed25519 AAAA...rest-of-key... user@hostname"
Add-Content -Path "C:\ProgramData\ssh\administrators_authorized_keys" -Value $key

# Set permissions
icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r
icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /grant "SYSTEM:(F)"
icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /grant "Administrators:(F)"

Step 5: Create SSH Config Files

Instead of typing ssh [email protected], create aliases like ssh laptop.

On Linux/macOS

# Create/edit ~/.ssh/config
cat > ~/.ssh/config << 'EOF'
# Laptop 1
Host laptop1
    HostName 100.x.x.1
    User yourusername
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

# Laptop 2
Host laptop2
    HostName 100.x.x.2
    User otherusername
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

# Server
Host server1
    HostName 100.x.x.3
    User serveruser
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

# Mac Mini
Host macmini
    HostName 100.x.x.4
    User macuser
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
EOF

# Set correct permissions
chmod 600 ~/.ssh/config

On Windows (PowerShell)

$config = @"
# Laptop 1
Host laptop1
    HostName 100.x.x.1
    User yourusername
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

# Laptop 2
Host laptop2
    HostName 100.x.x.2
    User otherusername
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

# Server
Host server1
    HostName 100.x.x.3
    User serveruser
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

# Mac Mini
Host macmini
    HostName 100.x.x.4
    User macuser
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
"@

Set-Content -Path "$env:USERPROFILE\.ssh\config" -Value $config

Important: The IdentitiesOnly yes option prevents the “Too many authentication failures” error when you have multiple SSH keys.

Step 6: Test Connections

From any machine, try connecting to others:

# Test individual connections
ssh laptop1 "hostname"
ssh server1 "whoami"
ssh macmini "uptime"

# Test from one machine to another and then to a third
ssh laptop1 'ssh server1 "echo Connected through laptop1 to server1"'

If everything works, you should connect without any password prompts!

Troubleshooting

“Permission denied (publickey)”

  • Verify the public key is in authorized_keys:# On the target machine cat ~/.ssh/authorized_keys
  • Check permissions:
    • Linux/macOS: ~/.ssh should be 700authorized_keys should be 600
    • Windows: Use icacls as shown above
  • For Windows administrators: Make sure the key is in C:\ProgramData\ssh\administrators_authorized_keys

“Too many authentication failures”

Add IdentitiesOnly yes to your SSH config file (shown above).

Can’t connect but Tailscale ping works

# Verify Tailscale connectivity
tailscale ping 100.x.x.x

# Check if SSH is listening
# On target machine
netstat -an | grep :22  # Linux/macOS
netstat -an | Select-String ":22"  # Windows PowerShell

SSH asks for passphrase

Your SSH key has a passphrase. Either:

  1. Use ssh-agent to cache the passphrase, OR
  2. Generate a new key without a passphrase (as shown in Step 3)

Security Considerations

  1. Private keys never leave their machine – only public keys are shared
  2. Tailscale provides the network security – SSH traffic is already encrypted by Tailscale
  3. Passwordless keys are safe when:
    • The private key file is protected (correct permissions)
    • The machine itself is secured (disk encryption, strong login password)
    • You trust the Tailscale network (all machines are yours or your team’s)
  4. For extra security:
    • Use PasswordAuthentication no in /etc/ssh/sshd_config to disable password login entirely
    • Use Tailscale ACLs to restrict which machines can connect to which
    • Consider keeping passphrases on keys for highly sensitive servers

The Full Mesh Matrix

Once completed, you’ll have this connection matrix:

From ↓ / To →laptop1laptop2server1macmini
laptop1
laptop2
server1
macmini

Automation Script

Here’s a helper script to test all connections from the current machine:

Linux/macOS

#!/bin/bash
# test-ssh-mesh.sh

HOSTS=("laptop1" "laptop2" "server1" "macmini")
CURRENT_HOST=$(hostname)

echo "Testing SSH connections from $CURRENT_HOST..."
echo "=========================================="

for host in "${HOSTS[@]}"; do
    if [ "$host" != "$CURRENT_HOST" ]; then
        echo -n "Testing $host... "
        if ssh -o ConnectTimeout=5 "$host" "echo OK" &>/dev/null; then
            echo "✅"
        else
            echo "❌"
        fi
    fi
done

Windows (PowerShell)

# test-ssh-mesh.ps1

$hosts = @("laptop1", "laptop2", "server1", "macmini")
$currentHost = hostname

Write-Host "Testing SSH connections from $currentHost..."
Write-Host "=========================================="

foreach ($host in $hosts) {
    if ($host -ne $currentHost) {
        Write-Host -NoNewline "Testing $host... "
        try {
            $result = ssh -o ConnectTimeout=5 $host "echo OK" 2>&1
            if ($LASTEXITCODE -eq 0) {
                Write-Host "✅" -ForegroundColor Green
            } else {
                Write-Host "❌" -ForegroundColor Red
            }
        } catch {
            Write-Host "❌" -ForegroundColor Red
        }
    }
}

Conclusion

You now have a fully connected mesh of machines where any system can SSH to any other without passwords! This setup is incredibly powerful for:

  • Running distributed tasks across machines
  • Quickly hopping between systems for maintenance
  • Setting up cluster computing
  • Remote development workflows
  • Automated deployment scripts

The combination of Tailscale’s secure network and SSH key authentication gives you both security and convenience. Enjoy your passwordless SSH mesh network!

Additional Resources

Share