SSH Agent forward specific keys rather than all registered ssh keys SSH Agent forward specific keys rather than all registered ssh keys linux linux

SSH Agent forward specific keys rather than all registered ssh keys


The keys themselves are not shared by forwarding your agent. What's forwarded is the ability to contact the ssh-agent on your local host. Remote systems send challenge requests through the forwarding tunnel. They do not request the keys themselves.

See http://www.unixwiz.net/techtips/ssh-agent-forwarding.html#fwd for a graphical explanation.


Looks like it is possible with OpenSSH 6.7 - it supports unix socket forwarding. We could start secondary ssh-agent with specific keys and forward it's socket to remote host. Unfortunately this version is not available for my server/client systems at the time of writing.

I have found another possible solution, using socat and standard SSH TCP forwarding.

Idea

  1. On local host we run secondary ssh-agent with only keys we want to see on remote host.
  2. On local host we set up forwarding of TCP connections on some port (portXXX) to secondary ssh-agent's socket.
  3. On remote host we set up forwarding from some socket to some TCP port (portYYY).
  4. Then we establish ssh connection with port forwarding from remote's portYYY to local portXXX.

Requests to ssh agent go like this:

local ssh-agent (secondary)    ^    |    v/tmp/ssh-.../agent.ZZZZZ   - agent's socket    ^    |   (socat local)    vlocalhost:portXXX    ^    |   (ssh port forwarding)    v remote's localhost:portYYY    ^    |   (socat remote)    v $HOME/tmp/agent.socket    ^    |   (requests for auth via agent)    v SSH_AUTH_SOCK=$HOME/tmp/agent.socket    ^    |   (uses SSH_AUTH_SOCK variable to find agent socket)    v   ssh

Drawbacks

  1. It is not completely secure, because ssh-agent becomes partially available through TCP: users of remote host can connect to your local agent on 127.0.0.1:portYYY, and other users of your local host can connect on 127.0.0.1:portXXX. But they will see only limited set of keys you manually added to this agent. And, as AllenLuce mentioned, they can't grab it, they only could use it for authentication while agent is running.
  2. socat must be installed on remote host. But looks like it is possible to simply upload precompiled binary (I tested it on FreeBSD and it works).
  3. No automation: keys must be added manually via ssh-add, forwarding requires 2 extra processes (socat) to be run, multiple ssh connections must be managed manually.

So, this answer is probably just a proof of concept and not a production solution.

Let's see how it can be done.

Instruction

Client side (where ssh-agent is running)

Run new ssh-agent. It will be used for keys you want to see on remote host only.

$ ssh-agent # below is ssh-agent output, DO NOT ACTUALLY RUN THESE COMMANDS BELOWSSH_AUTH_SOCK=/tmp/ssh-qVnT0UsgV6yO/agent.22982; export SSH_AUTH_SOCK;SSH_AGENT_PID=22983; export SSH_AGENT_PID;

It prints some variables. Do not set them: you will loose your main ssh agent. Set another variable with suggested value of SSH_AUTH_SOCK:

SSH_AUTH_SECONDARY_SOCK=/tmp/ssh-qVnT0UsgV6yO/agent.22982

Then establish forwarding from some TCP port to our ssh-agent socket locally:

PORT=9898socat TCP4-LISTEN:$PORT,bind=127.0.0.1,fork UNIX-CONNECT:$SSH_AUTH_SECONDARY_SOCK &

socat will run in background. Do not forget to kill it when you're done.

Add some keys using ssh-add, but run it with modified enviromnent variable SSH_AUTH_SOCK:

SSH_AUTH_SOCK=$SSH_AUTH_SECONDARY_SOCK ssh-add

Server side (remote host)

Connect to remote host with port forwarding. Your main (not secondary) ssh agent will be used for auth on hostA (but will not be available from it, as we do not forward it).

home-host$ PORT=9898 # same port as abovehome-host$ ssh -R $PORT:localhost:$PORT userA@hostA

On remote host establish forwarding from ssh-agent socket to same TCP port as on your home host:

remote-host$ PORT=9898 # same port as on home hostremote-host$ mkdir -p $HOME/tmpremote-host$ SOCKET=$HOME/tmp/ssh-agent.socketremote-host$ socat UNIX-LISTEN:$SOCKET,fork TCP4:localhost:$PORT &

socat will run in background. Do not forget to kill it when you're done. It does not automatically exit when you close ssh connection.

Connection

On remote host set enviromnent variable for ssh to know where agent socket (from previous step) is. It can be done in same ssh session or in parallel one.

remote-host$ export SSH_AUTH_SOCK=$HOME/tmp/ssh-agent.socket

Now it is possible to use secondary agent's keys on remote host:

remote-host$ ssh userB@hostB # uses secondary ssh agentWelcome to hostB!