Getting to a server behind a bastion often starts with ssh -A bastion and a second ssh from there. The -A flag forwards your local authentication agent, so the bastion can use your keys for the next hop.
What a forwarded agent exposes
The ssh manual asks for caution with -A. Users on the remote host who can get past the file permissions on the agent’s Unix-domain socket can reach your local agent over the forwarded connection. In practice that is root, or anyone else who can open the socket despite its permissions.
The manual adds that such an attacker cannot extract the key material. They can still authenticate with the identities loaded in your agent while the connection is open. Confirmation prompts and destination constraints still apply, and each target server still decides whether to accept the key.
ProxyJump reaches the inner host over TCP
The same -A entry suggests a jump host (-J) as a possibly safer choice. With -J, ssh connects to the jump host and sets up a TCP forwarding from there to the destination. Your local client runs the inner session through that forward.
In the OpenSSH client source, the jump connection is built as an ssh -W stdio forward. That mode opens no session on the bastion, and the client requests agent forwarding only while setting up a session. An ordinary ProxyJump therefore does not normally give the bastion an agent socket, even when a ForwardAgent yes line matches it. The ssh_config manual gives no as the default for ForwardAgent.
For a single connection:
ssh -J [email protected] [email protected]
For regular use, put it in ~/.ssh/config. The ssh manual notes that command-line options mostly affect the destination and leave jump hosts alone, so bastion settings belong in the file:
Host bastion
HostName bastion.example.com
User admin
ForwardAgent no
Host app
HostName 10.0.0.12
User app
ProxyJump bastion
Then ssh app passes through the bastion over a TCP forward. Our advice: keep ForwardAgent no on the bastion entry anyway. It states the intent for that host and also covers a direct ssh bastion login.
When the remote host needs your key
Some jobs run on the remote host itself, such as cloning a private repository there. If you must forward, the ssh-add manual offers three limits. -c asks for confirmation before each use of a key. -t caps how long a key stays loaded. -h adds destination constraints, which limit a forwarded key to the hops you list.
Destination constraints arrived in OpenSSH 8.9. Over a forwarded agent, the remote ssh client and the server both have to support them. The manual also warns that someone holding the remote agent socket can still forward it again, though only toward a destination you permitted.
What to do
- Run
ssh -G <host>for the bastion and for the inner host. It prints the evaluated configuration, including the effectiveforwardagentvalue. - Remove
ForwardAgent yesfrom anyHost *block, and setForwardAgent noon the bastion entry. - Replace
ssh -Ahops withProxyJumpor-J. - Where forwarding has to stay, enable it for that one host and load the key with
ssh-add -c -t 3600. Our advice: use the shortest lifetime that fits the job.

The Campfire
CommentsThanks. Your comment is waiting for the desk. Once it is approved it appears here within about a minute.
Add a comment