About SSH Agent

Introduction


SSH-agent is part of OpenSSH. In this post I will explain what an agent is, how to use it and how it works to keep your keys safe. I will also describe agent forwarding and how it works. I will help you reduce the risk of using agent forwarding and will share an alternative to agent forwarding that you can use when accessing your internal hosts through bastions.

What is an SSH agent


ssh-agentIs a key manager for SSH. It stores your keys and certificates in memory, unencrypted and ready for use ssh. This eliminates the need to enter a password each time you connect to the server. It runs in the background on your system, separate from ssh, and usually starts on the first start ssh.

The SSH agent keeps secret keys safe because it does not :

  • It does not write any key information to disk.
  • It does not allow you to export your private keys.

Secret keys stored in the Agent can be used for only one purpose: signing a message.

But if an agent can only sign messages, how does SSH encrypt and decrypt traffic?

In the first study of SSH public and private keys, it is natural to assume that SSH uses these key pairs to encrypt and decrypt traffic. That is exactly what I thought. But this is not the case. The SSH key pair is used only for authentication during the initial connection.

For example, here's how to verify a user key during an SSH connection, from a server perspective:

  • The client provides the server with a public key.
  • The server generates and sends a short random message asking the client to sign it using a private key.
  • The client asks the SSH agent to sign the message and sends the result back to the server.
  • The server verifies the signature using the clientโ€™s public key.
  • Now the server has proof that the client owns the private key.

Later, during the connection process, a set of new, ephemeral and symmetric keys are generated, which are used to encrypt SSH session traffic. These keys may not even last an entire session; The rekey event occurs at regular intervals.

Agent Protocol


SSH uses a Unix domain socket to communicate with the agent over the SSH agent protocol . Most people use the ssh-agentone that comes with OpenSSH, but there are many open source alternatives.

The agent protocol is so simple that you could write a basic SSH-agent in a day or two. It has only a few basic operations:

  • Add a regular key pair (public and decrypted private keys)
  • Add a limited key pair (public and decrypted private keys)
  • Add key (regular or limited) from smart card (public key only)
  • Delete key
  • Listing keys stored in the agent
  • Signing a message with a key stored in the agent
  • Lock or unlock an entire agent with a password

What is a limited key? This is usually a key that either has a limited life or requires explicit confirmation by the user when using it.

The command ssh-addis your gateway to the SSH agent. He performs all these operations except for the signature. When you run ssh-add without any parameters, it will scan your home directory for some standard keys and add them to your agent. By default, it searches for:

  • ~/.ssh/id_rsa
  • ~/.ssh/id_ed25519
  • ~/.ssh/id_dsa
  • ~/.ssh/id_ecdsa

As soon as you add the keys to the keychain, they will be automatically used ssh.

ssh-and macOS Keychain
ssh-agent , shipped with macOS, can store passphrase for keys in macOS Keychain, which makes it even easier to re-add keys to the agent after a reboot. Depending on your Keychain settings, you may still need to unlock it after a reboot. To save key passphrases to Keychain, run the command ssh-add -K [ ]. Passphrases are usually stored in โ€œLocal Itemsโ€. ssh-agentwill use these saved passphrases automatically as needed.

What is agent forwarding


The agent forwarding feature allows your local SSH agent to communicate through an existing SSH connection and authenticate transparently to a more remote server. For example, suppose you log in to EC2 through SSH and want to clone a private GitHub repository from there. Without agent forwarding, you will have to store a copy of your GitHub private key on the EC2 host. When agent is being redirected, the SSH client on EC2 can use the keys on your local computer for authentication on GitHub.

How agent forwarding works


Firstly, a little background. SSH connections can have multiple channels. Here is a common example: an interactive connection to bastion-host (jump box) is performed on one channel. When agent forwarding is enabled for the connection (usually using ssh -A), a second channel opens in the background to forward any agent requests back to your local computer.

In terms of ssh, there is no difference between remote and local ssh-agent. SSH always looks at the environment variable $SSH_AUTH_SOCKto find the Unix domain socket for the agent. When connecting to a remote host with agent forwarding enabled, SSHD will create a remote Unix domain socket that is associated with the agent forwarding channel and export $SSH_AUTH_SOCKthat points to it.

image

Agent forwarding is associated with a certain risk


When you redirect a ssh-agentUnix domain socket to a remote host, this poses a security risk: anyone with root access on the remote host can discreetly access your local SSH-agent through the socket. They can use your keys to impersonate you on other machines on the network.

Here is an example of how this might look:

image

How to reduce your risk with agent forwarding


Here are some ways to make agent redirection more secure:

  • Do not enable ForwardAgentby default.


Block your ssh agent when you use agent forwarding. ssh-add -xblocks the agent with a password, and ssh-add -Xunlocks it. When you are connected to a remote host with agent forwarding, no one can enter your agent without a password.

Or use an alternate SSH agent that asks you when it is in use. Sekey uses Touch ID on macOS to store keys in the MacBook Pro security enclave.

Or do not use agent forwarding at all. If you are trying to access internal hosts through bastion, there ProxyJumpis a much safer alternative for this use case. (see below)

Use ProxyJump: a safer alternative


When you want to go through bastion-host (jumpbox), you really don't need agent'a forwarding. The best approach is to use the directive ProxyJump.

Instead of redirecting the agent through a separate channel, it ProxyJumpredirects the standard input and output of your local SSH client through bastion and further to the remote host. Here's how it works:

  1. Run ssh -J bastion.example.com cloud.computer.internalto connect to cloud.computer.internalthrough your bastion host bastion.example.com. cloud.computer.internalIs the host name that can be found by searching DNS on bastion.example.com.
  2. Your SSH client uses the keys from your agent to connect to bastion.example.com.
  3. After connecting SSHD to bastion, it connects to cloud.computer.internaland transfers this connection to your local SSH client.
  4. Your local SSH client goes through the connection again, this time with cloud.computer.internal

You can think of it as SSH in an SSH session; except that ssh never runs on bastion. Instead, it sshdconnects to cloud.computer.internaland gives control of this connection (standard input and output) back to your local SSH, which then makes a second connection.

Configuring ProxyJump

Let's say bastion-host this bastion.example.com. I can configure my ~/.ssh/configlike this:

Host bastion.example.com
	User carl

Host *.computer.internal
	ProxyJump bastion.example.com
	User carl

Then I just run ssh cloud.computer.internalto connect to the internal destination via bastion - without agent forwarding.

If ProxyJump does not work ...

Older versions of SSH and SSHD (prior to version 7.2, released in 2016) do not support ProxyJump. But you can perform an equivalent operation using ProxyCommandand netcat . Here is an example:

ssh -o ProxyCommand="ssh bastion.example.com nc %h %p" cloud.computer.internal

The magic here is that SSH itself is the proxy server you use for SSH. The part nc %h %psimply opens the raw socket connection to cloud.computer.internalon port 22. The standard input / output of the parent ssh command is passed directly to ProxyCommandso that the parent ssh can authenticate to the internal host through a proxy connection.



image
Learn the details of how to get a sought-after profession from scratch or Level Up in skills and salary by taking SkillFactory online courses:



Read more



All Articles