SSH ProxyJump: Connect Through a Bastion Host with ~/.ssh/config
2026-10-12
If your servers sit in a private network and the only way in is through a bastion (also called a jump host), you do not need to SSH twice by hand. OpenSSH can hop through the bastion for you, and it takes three lines of config.
The one-off version: -J
ssh -J [email protected] [email protected]
-J (ProxyJump) tells ssh to connect to the bastion first, then open the real connection through it. Your keys stay on your machine: the bastion only forwards the encrypted stream.
The permanent version: ~/.ssh/config
Put the bastion and the internal hosts in ~/.ssh/config:
Host bastion
HostName bastion.example.com
User ops
IdentityFile ~/.ssh/id_ed25519
Host app1 app2
HostName 10.0.5.20
User deploy
ProxyJump bastion
Now ssh app1 goes through bastion by itself. Host app1 app2 gives the same entry two names, which is handy when a server has an old and a new alias.
More than one hop
Separate the hops with commas, in the order you cross them:
ssh -J ops@bastion1,ops@bastion2 [email protected]
or in the config: ProxyJump bastion1,bastion2.
scp, rsync and port forwarding use the same config
Because the hop lives in the config, every tool that calls ssh picks it up:
scp ./release.tar.gz app1:/tmp/
rsync -avz ./site/ app1:/var/www/site/
ssh -L 5432:localhost:5432 app1
For one-off scp without a config entry, use scp -J ops@bastion ....
Older OpenSSH: ProxyCommand
ProxyJump needs OpenSSH 7.3 or newer. On older clients the equivalent is:
Host app1
HostName 10.0.5.20
ProxyCommand ssh -W %h:%p bastion
Check what ssh will actually do
When a hop does not work, ask ssh to print the final settings instead of guessing:
ssh -G app1 | grep -i -E "^(hostname|user|proxyjump|port) "
and watch the handshake with ssh -v app1. The usual causes are: the bastion's key is not loaded (ssh-add -l), the internal host only accepts a different user, or the bastion's AllowTcpForwarding is set to no.
Do not forward your agent through the bastion
ForwardAgent yes lets anyone with root on the bastion use your keys while you are connected. With ProxyJump you do not need it for the hop itself, so leave it off.
FAQ
Is ProxyJump the same as a VPN? No. It only tunnels the SSH connection you start; nothing else on your machine is routed through the bastion.
Can I jump through a host that uses a different port? Yes: -J ops@bastion:2222 or Port 2222 in the bastion's Host block.
Why does ssh app1 ask for the bastion's password? ssh authenticates each hop separately. Add your key to the bastion with ssh-copy-id bastion, then it will not prompt.
Shortcut
Disclosure: we make Harbor. Harbor is an SSH terminal for Mac that uses your own ssh and ~/.ssh/config, keeps jump hosts apart as gateways, shows live server stats and, with Pro, a post-mortem that reads the server's own history. The terminal, stats and a read-only database client are free. See Harbor.