guest@6admin.io:~$

SSH: ProxyJump and modern multi-hop

A few years ago, to reach a machine behind a bastion, I wrote a ProxyCommand with nc and I told that story in SSH: tunneling . OpenSSH 7.3 made all of that obsolete with a single option, -J and it is one of those small additions that change a gesture you make ten times a day.

The basic gesture

ssh -J user@bastion user@target

bastion acts as the jump host, the target is never exposed directly and above all the encryption stays end to end between your machine and target. The bastion only sees encrypted traffic it cannot read, exactly as with the old ProxyCommand, but without invoking nc or opening an intermediate shell. The difference with ProxyCommand is not merely cosmetic: -J establishes the connection to the next hop from the client, not from the bastion, so no private key transits or sits on the jump host. That is what we wanted from the start and what we used to hack around with agent forwarding, which posed precisely the opposite problem by exposing the agent on the bastion.

Several jump hosts

The chain extends by listing the hops in order:

ssh -J user@bastion1,user@bastion2 user@target

Each jump host relays to the next and the encrypted tunnel is still negotiated end to end with the final target.

In config, so you never think about it again

The real comfort is in ~/.ssh/config, where ProxyJump pins the jump host once and for all:

Host target
    HostName 10.0.0.42
    User deploy
    ProxyJump user@bastion

After which a plain ssh target goes through the bastion without a thought and everything built on ssh, scp, rsync, port forwards, inherits the jump host with no extra configuration.

In practice

ProxyJump does nothing ProxyCommand could not do, it does it cleanly: a short syntax, a readable config entry and the guarantee that the key never leaves the originating machine. The old ProxyCommand + nc keeps its use the day nc is the only tool available on a stubborn jump host, but for everything else, -J has become the default gesture.

[edit: 2026] The Ansible implementation of all this: the ssh role .