SSH代理转发特定密钥而不是所有已注册的ssh密钥

use*_*535 11 linux ssh github ssh-keys amazon-web-services

我正在使用代理转发,它工作正常.但是ssh客户端正在与远程服务器共享所有已注册的(ssh-add)密钥.我有个人密钥,我不想与远程服务器共享.有没有办法限制密钥被转发?

我有多个github帐户和aws帐户.我不想分享所有的ssh-key.

cro*_*nfy 6

看起来 OpenSSH 6.7 可以实现 - 它支持 unix 套接字转发。我们可以使用特定密钥启动辅助 ssh-agent 并将其套接字转发到远程主机。不幸的是,在撰写本文时,该版本不适用于我的服务器/客户端系统。

我找到了另一种可能的解决方案,使用socat和标准 SSH TCP 转发。

主意

  1. 在本地主机上,我们运行辅助 ssh-agent,仅使用我们希望在远程主机上看到的密钥。
  2. 在本地主机上,我们设置将某个端口 (portXXX) 上的 TCP 连接转发到辅助 ssh-agent 的套接字。
  3. 在远程主机上,我们设置从某个套接字到某个 TCP 端口 (portYYY) 的转发。
  4. 然后我们建立 ssh 连接,端口转发从远程的 portYYY 到本地的 portXXX。

对 ssh 代理的请求如下所示:

local ssh-agent (secondary)
    ^
    |
    v
/tmp/ssh-.../agent.ZZZZZ   - agent's socket
    ^
    |   (socat local)
    v
localhost: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
Run Code Online (Sandbox Code Playgroud)

缺点

  1. 它并不完全安全,因为 ssh-agent 通过 TCP 变得部分可用:远程主机的用户可以连接到 127.0.0.1:portYYY 上的本地代理,本地主机的其他用户可以连接到 127.0.0.1:portXXX 上。但他们只会看到您手动添加到此代理的有限密钥集。而且,正如AllenLuce 提到的,他们无法获取它,只能在代理运行时使用它进行身份验证。
  2. socat必须安装在远程主机上。但看起来可以简单地上传预编译的二进制文件(我在 FreeBSD 上测试了它并且它有效)。
  3. 无自动化:必须通过 手动添加密钥ssh-add,转发需要运行 2 个额外进程 (socat),必须手动管理多个 ssh 连接。

因此,这个答案可能只是概念证明,而不是生产解决方案。

让我们看看如何做到这一点。

操作说明

客户端(运行 ssh-agent 的地方)

运行新的 ssh-agent。它将用于您只想在远程主机上看到的密钥。

$ ssh-agent # below is ssh-agent output, DO NOT ACTUALLY RUN THESE COMMANDS BELOW
SSH_AUTH_SOCK=/tmp/ssh-qVnT0UsgV6yO/agent.22982; export SSH_AUTH_SOCK;
SSH_AGENT_PID=22983; export SSH_AGENT_PID;
Run Code Online (Sandbox Code Playgroud)

它打印一些变量。不要设置它们:您将失去主要的 ssh 代理。设置另一个变量的建议值为SSH_AUTH_SOCK

SSH_AUTH_SECONDARY_SOCK=/tmp/ssh-qVnT0UsgV6yO/agent.22982
Run Code Online (Sandbox Code Playgroud)

然后在本地建立从某个 TCP 端口到我们的 ssh-agent 套接字的转发:

PORT=9898
socat TCP4-LISTEN:$PORT,bind=127.0.0.1,fork UNIX-CONNECT:$SSH_AUTH_SECONDARY_SOCK &
Run Code Online (Sandbox Code Playgroud)

socat将在后台运行。kill完成后不要忘记它。

使用添加一些键ssh-add,但使用修改后的环境变量运行它SSH_AUTH_SOCK

SSH_AUTH_SOCK=$SSH_AUTH_SECONDARY_SOCK ssh-add
Run Code Online (Sandbox Code Playgroud)

服务器端(远程主机)

通过端口转发连接到远程主机。您的主要(而非辅助)ssh 代理将用于在 hostA 上进行身份验证(但无法从中使用,因为我们不转发它)。

home-host$ PORT=9898 # same port as above
home-host$ ssh -R $PORT:localhost:$PORT userA@hostA
Run Code Online (Sandbox Code Playgroud)

在远程主机上建立从 ssh-agent 套接字到与本地主机上相同的 TCP 端口的转发:

remote-host$ PORT=9898 # same port as on home host
remote-host$ mkdir -p $HOME/tmp
remote-host$ SOCKET=$HOME/tmp/ssh-agent.socket
remote-host$ socat UNIX-LISTEN:$SOCKET,fork TCP4:localhost:$PORT &
Run Code Online (Sandbox Code Playgroud)

socat将在后台运行。kill完成后不要忘记它。当您关闭 ssh 连接时,它不会自动退出。

联系

在远程主机上为 ssh 设置环境变量以了解代理套接字(来自上一步)在哪里。它可以在同一个 ssh 会话中或并行会话中完成。

remote-host$ export SSH_AUTH_SOCK=$HOME/tmp/ssh-agent.socket
Run Code Online (Sandbox Code Playgroud)

现在可以在远程主机上使用辅助代理的密钥:

remote-host$ ssh userB@hostB # uses secondary ssh agent
Welcome to hostB!
Run Code Online (Sandbox Code Playgroud)


All*_*uce 4

转发您的代理不会共享密钥本身。转发的是联系本地主机上的 ssh 代理的能力。远程系统通过转发隧道发送质询请求。他们自己并不要求钥匙。

请参阅http://www.unixwiz.net/techtips/ssh-agent-forwarding.html#fwd了解图形说明。