Safer SSH agent forwarding

Vincent Bernat

ssh-agent is a program to hold in memory the private keys used by SSH for public-key authentication. When the agent is running, ssh forwards to it the signature requests from the server. The agent performs the private key operations and returns the results to ssh. It is useful if you keep your private keys encrypted on disk and you don’t want to type the password at each connection. Keeping the agent secure is critical: someone able to communicate with the agent can authenticate on your behalf on remote servers.

ssh also provides the ability to forward the agent to a remote server. From this remote server, you can authenticate to another server using your local agent, without copying your private key on the intermediate server. As stated in the manual page, this is dangerous!

Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the agent’s UNIX-domain socket) can access the local agent through the forwarded connection. An attacker cannot obtain key material from the agent, however they can perform operations on the keys that enable them to authenticate using the identities loaded into the agent. A safer alternative may be to use a jump host (see -J).

Update (2022-10)

See for example Matrix’ 2019 post-mortem about their security incident involving unsafe SSH agent forwarding.

As mentioned, a better alternative is to use the jump host feature: the SSH connection to the target host is tunneled through the SSH connection to the jump host. See the manual page and this blog post for more details.

If you really need to use SSH agent forwarding, you can secure it a bit through a dedicated agent with two main attributes:

  • it holds only the private key to connect to the target host; and
  • it asks confirmation for each requested signature.

The following alias around the ssh command will spawn such an ephemeral agent:

alias assh="ssh-agent ssh -o AddKeysToAgent=confirm -o ForwardAgent=yes"

With the -o AddKeysToAgent=confirm directive, ssh adds the unencrypted private key to the agent but each use must be confirmed.1 Once connected, you get a password prompt for each signature request:2

ssh-agent prompt confirmation with fingerprint and yes/no buttons
Request for the agent to use the specified private key

But, again, avoid using agent forwarding! ☠️

Update (2020-04)

In a previous version of this article, the wrapper around the ssh command was a more complex function. Alexandre Oliva was kind enough to point me to the simpler solution above.

Update (2020-04)

Guardian Agent is an even safer alternative: it shows and ensures the usage (target and command) of the requested signature. There is also a wide range of alternative solutions to this problem. See for example SSH-Ident, Wikimedia solution and solo-agent.

Update (2022-01)

OpenSSH 8.9 will be able to restrict usage of forwarded SSH agent keys. However, the protection offered by these restrictions is quite limited. You should continue to avoid using agent forwarding.

  1. Alternatively, you can add the keys with ssh-add -c↩︎

  2. Unfortunately, the dialog box default answer is “Yes.” ↩︎