Skip to content
rr homev0.29.3
Docs menu

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-machine

Done. Skip to Verify it works.

Full walkthrough

1. Check for existing SSH keys

ls ~/.ssh/id_*.pub

If 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.pub

3. Copy your key to the remote

The easiest way:

ssh-copy-id user@your-remote-machine

Replace 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_ed25519

Add this to ~/.ssh/config to auto-load from keychain:

Host *
    UseKeychain yes
    AddKeysToAgent yes

Linux

Start the agent and add your key:

eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519

To 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
fi

Setting 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 yes

Now 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 yes

Then 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-machine

This will:

  1. Generate an ed25519 key if you don’t have one
  2. Test the connection
  3. 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 -l

If empty, add your key:

ssh-add ~/.ssh/id_ed25519

Check 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 exit

If the key changed and you trust the change:

ssh-keygen -R your-remote-machine
ssh user@your-remote-machine   # Accept the new key

Next 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

View as Markdown