SSH setup
Before using rr, you need passwordless SSH access to your remote machine. This guide walks through setting that up.
Prerequisites
- A remote machine running SSH (Linux, macOS, or WSL)
- Network access to that machine (LAN, VPN, or internet)
Quick version
If you already have SSH keys and just need to copy them to a new machine:
ssh-copy-id user@your-remote-machineDone. Skip to Verify it works.
Full walkthrough
1. Check for existing SSH keys
ls ~/.ssh/id_*.pubIf you see files like id_ed25519.pub or id_rsa.pub, you already have keys. Skip to Copy your key to the remote.
If you get “No such file or directory”, continue to generate new keys.
2. Generate an SSH key
ssh-keygen -t ed25519 -C "[email protected]"Press Enter to accept the default location (~/.ssh/id_ed25519).
Passphrase: You can set one for extra security or leave it empty for convenience. If you set one, you’ll need to use ssh-agent (covered below).
Example output:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/you/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Your identification has been saved in /Users/you/.ssh/id_ed25519
Your public key has been saved in /Users/you/.ssh/id_ed25519.pub3. Copy your key to the remote
The easiest way:
ssh-copy-id user@your-remote-machineReplace user with your username on the remote machine (often the same as your local username).
You’ll be prompted for the remote password one last time. After this, you won’t need it again.
If ssh-copy-id isn’t available (some macOS versions), do it manually:
cat ~/.ssh/id_ed25519.pub | ssh user@your-remote-machine "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"4. Verify it works
ssh user@your-remote-machine "echo 'SSH is working'"If this prints “SSH is working” without asking for a password, you’re done.
This first connection also matters for another reason: rr verifies host keys against ~/.ssh/known_hosts and never prompts to accept a new one. Connect with ssh once per hostname or alias you list in rr’s config, so the key gets recorded. Otherwise rr fails with a host key error (SSH_HOST_KEY).
Using ssh-agent (for passphrase-protected keys)
If you set a passphrase on your key, you’ll want ssh-agent to remember it so you don’t type it constantly.
macOS
macOS has built-in keychain integration:
# Add key to keychain
ssh-add --apple-use-keychain ~/.ssh/id_ed25519Add this to ~/.ssh/config to auto-load from keychain:
Host *
UseKeychain yes
AddKeysToAgent yesLinux
Start the agent and add your key:
eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519To persist across terminal sessions, add to your ~/.bashrc or ~/.zshrc:
if [ -z "$SSH_AUTH_SOCK" ]; then
eval $(ssh-agent -s) > /dev/null
ssh-add ~/.ssh/id_ed25519 2>/dev/null
fiSetting up an SSH config alias
SSH config aliases make your life easier. Instead of typing ssh [email protected], you can type ssh devbox.
Edit ~/.ssh/config (create it if it doesn’t exist):
Host devbox
HostName 192.168.1.50
User riley
IdentityFile ~/.ssh/id_ed25519
AddKeysToAgent yes
UseKeychain yesNow ssh devbox connects to [email protected] using your key.
Important: The AddKeysToAgent and UseKeychain options (macOS) ensure your key is automatically loaded into the SSH agent. This is required for rr to work with passphrase-protected keys, since rr cannot prompt for passphrases interactively.
The IdentityFile line tells SSH which private key to use. This is what makes the connection passwordless (assuming you’ve copied the public key to the remote with ssh-copy-id).
Multiple ways to reach the same machine
If your machine is reachable via LAN and Tailscale, set up both:
Host devbox-lan
HostName 192.168.1.50
User riley
IdentityFile ~/.ssh/id_ed25519
AddKeysToAgent yes
UseKeychain yes
Host devbox-tailscale
HostName devbox.tailnet-name.ts.net
User riley
IdentityFile ~/.ssh/id_ed25519
AddKeysToAgent yes
UseKeychain yesThen in your global config (~/.rr/config.yaml), list both and rr will use whichever one is reachable:
# ~/.rr/config.yaml
hosts:
devbox:
ssh:
- devbox-lan # Try LAN first (faster)
- devbox-tailscale # Fall back to Tailscale
dir: ~/projects/${PROJECT}Using rr setup
Once you have SSH working, rr setup can help configure additional machines:
rr setup user@new-machineThis will:
- Generate an ed25519 key if you don’t have one
- Test the connection
- If authentication fails, offer to copy your public key to the remote, then test again
How rr uses your SSH config
rr runs commands over its own SSH client, not ssh (sync uses rsync, which does use ssh). That client reads ~/.ssh/config but only understands part of it:
| Option | Supported |
|---|---|
HostName, Port, User, IdentityFile |
Yes |
IdentityAgent (1Password, Secretive, YubiKey agents) |
Yes |
ProxyCommand |
Yes |
ProxyJump |
Yes. rr runs ssh -W to the jump host, as OpenSSH does, so the jump host is resolved through your config and your ssh. Chains (a,b) and ProxyJump none work. A ProxyCommand on the same host wins, where OpenSSH takes whichever comes first |
Match blocks |
No. Host entries after the first Match line aren’t seen, so put the hosts rr uses above it |
For authentication, rr tries the SSH agent first, then the IdentityFile from your config, then ~/.ssh/id_ed25519, ~/.ssh/id_rsa, and ~/.ssh/id_ecdsa. It can’t prompt for a passphrase, so passphrase-protected keys have to be loaded in the agent.
For throwaway CI machines where host keys change on every run, --no-strict-host-key-checking skips host key verification. Don’t use it for machines you care about.
Troubleshooting
“Permission denied (publickey)”
Your key isn’t on the remote, or permissions are wrong.
Check your key is loaded:
ssh-add -lIf empty, add your key:
ssh-add ~/.ssh/id_ed25519Check remote permissions:
ssh user@remote "ls -la ~/.ssh"The .ssh directory should be 700 (drwx——) and authorized_keys should be 600 (-rw—––).
Fix if needed:
ssh user@remote "chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"“Connection refused”
SSH server isn’t running on the remote.
# On the remote machine:
sudo systemctl status sshd # Check status
sudo systemctl start sshd # Start if not running“Connection timed out”
The remote machine isn’t reachable. Check:
- Is it powered on?
- Are you on the right network (LAN vs VPN)?
- Is a firewall blocking port 22?
# Test if port 22 is reachable
nc -zv your-remote-machine 22“Host key verification failed”
Either you haven’t connected with ssh yet (rr won’t add new keys to known_hosts for you), or the remote machine’s key changed (reinstalled OS, different machine at same IP, etc.).
First connection:
ssh -o StrictHostKeyChecking=accept-new your-remote-machine exitIf the key changed and you trust the change:
ssh-keygen -R your-remote-machine
ssh user@your-remote-machine # Accept the new keyNext steps
Once SSH is working:
cd your-project
rr init # Set up rr for this project
rr doctor # Verify everything works
rr run "echo hello" # Test it out