SSH Config and Jump Hosts

The Client Config File, Agents and Jump Hosts

~/.ssh/config turns ssh -i ~/.ssh/id_ed25519 bk3ssh@localhost into ssh web1, and scp, rsync 13,872 and VS Code 550 Remote-SSH read it too. Like sshd, the client keeps the first value it finds for each option, so specific Host blocks go first and the Host * defaults last:

~/.ssh/config with an alias, a jump host and connection sharingShell
Host web1
  HostName localhost
  User bk3ssh
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
Host app1
  HostName 127.0.0.1
  User bk3ssh
  ProxyJump web1
Host *
  AddKeysToAgent yes
  ControlMaster auto
  ControlPath ~/.ssh/cm-%C
  ControlPersist 10m

app1 stands for a private server only web1 can reach. ProxyJump has web1 open a TCP connection onward and runs a second, end-to-end encrypted session through it, so HostName resolves on the jump host. ssh -G prints the settings a host would get:

Checking the resolved settings, then hopping through the jump hostShell
ssh -G app1 | grep -E '^(user|hostname|proxyjump) '
ssh app1 'echo "arrived from: $SSH_CONNECTION"'
Output
user bk3ssh
hostname 127.0.0.1
proxyjump web1
arrived from: 127.0.0.1 38356 127.0.0.1 22

With ControlMaster, later connections reuse the first one's session: a second ssh web1 true took 0.129 s instead of 0.741 s here. ssh -O exit web1 closes it. ssh-agent holds decrypted keys in memory: start it with eval "$(ssh-agent -s)", load a key with ssh-add, list keys with ssh-add -l. Since OpenSSH 10.1 23,707 its socket lives under ~/.ssh/agent/, not /tmp. On Windows the agent is a service that ships disabled.