All articles

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.