Skip to content
Latchkey

ssh -J / ProxyJump: Reach a Host Through a Bastion

ssh -J jump connects to the final host by tunneling through one or more intermediate bastion hosts.

Production hosts often sit behind a bastion. ProxyJump reaches them in one command without agent forwarding, which makes it the safer choice for multi-hop deploys.

What it does

ssh -J (ProxyJump) establishes a connection to each jump host in turn and tunnels the final connection through them. Authentication to the target happens end to end from the runner, so the bastion never sees the target session's plaintext.

Common usage

Terminal
ssh -J bastion.example.com user@internal-host
# multiple jumps, comma-separated, with a specific user/port on the jump
ssh -J jumpuser@bastion:2222 user@10.0.0.5 "deploy.sh"
# the config equivalent
# Host internal
#   HostName 10.0.0.5
#   ProxyJump jumpuser@bastion

Options

FormWhat it does
-J <host>Jump through one bastion
-J <h1>,<h2>Chain multiple jump hosts in order
-J user@host:portSet user and port on the jump host
ProxyJump (config)Same behavior declared per host

In CI

Seed known_hosts for both the bastion and the target with ssh-keyscan, since strict checking applies to every hop. ProxyJump is preferable to agent forwarding (-A) because the bastion cannot use your keys for anything else. Each hop authenticates independently, so authorize the runner key on both.

Common errors in CI

Host key verification failed. can come from either hop; keyscan and add both hosts. "Permission denied (publickey)" on the target means the key is not authorized there even if the bastion accepted it. "channel 0: open failed: administratively prohibited" means the bastion forbids forwarding to that destination; check its sshd AllowTcpForwarding and any match rules.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →