转发到 docker 容器的透明 ssh 连接



我希望有一个服务器来透明地将传入的 ssh 连接从客户端转发到 docker 容器。这应该包括 scp、git 传输等。这必须与密钥一起使用,密码将被停用。用户不应看到服务器。更新:是的,这实际上意味着用户将不知道有服务器。配置必须完全在服务器上进行!

client -----> server -----> container  (actual connection)
client -------------------> container  (what the user should see)

所以,给出的是这样的:

user@client$ ssh user@server
user@server$ ssh -p 42 user@localhost
user@container$ 

但我想要的是这个:

user@client$ ssh user@server
user@container$ 

我尝试在authorized_keys文件中使用command="ssh -p 42 user@localhost"语法,这有点有效,只是在第二个 ssh 连接中,用户必须输入他们的密码,因为身份验证未通过(server没有私钥user(。 此外,即使输入密码,此方法也不适用于scp

我也听说过tunnel=命令,但我不知道如何设置它(而且手册页没有多大帮助(。

我在 Arch 上使用 OpenSSH 7.5p1。

把它放在你的~/.ssh/config文件中:

Host server-container
ProxyCommand ssh server -W localhost:42

然后只需执行以下操作:

ssh server-container

只要您的用户名一致。如果没有,您可以按如下方式指定它们:

Host server-container
ProxyCommand ssh server-user@server -W localhost:42

然后只需执行以下操作:

ssh container-user@server-container

作为奖励,您可以避免使用 ssh 使用docker exec进入容器。喜欢这个:

ssh -t server docker exec -it <container-id> bash

这就是我现在想出的解决方案。我对第二个键有点不满意,因为它的公共部分将在container~/.ssh/authorized_keys中可见,这稍微破坏了透明度,但除此之外,所有其他事情似乎都有效。

user@server$ cat .ssh/authorized_keys
command="ssh  -q -p 42 user@localhost -- "$SSH_ORIGINAL_COMMAND"",no-X11-forwarding ssh-rsa <KEYSTRING_1>
user@server$ cat .ssh/id_rsa.pub
<KEYSTRING_2>
user@container$ cat .ssh/authorized_keys
ssh-rsa <KEYSTRING_2>
client

授权使用其私钥进行server。然后,服务器使用专用密钥跳转到container,该密钥仅用于该特定身份验证。我有点担心您可以通过注入一些命令来突破command=,但到目前为止,我没有发现允许突破的排列。
由于传递$SSH_ORIGINAL_COMMAND,您甚至可以做scpssh-copy-id等等。

注意:要禁止ssh-copy-id,我出于其他原因想要这样做,只需将容器内的userauthorized_keys设置为不可写。

这将是两部分:

  • 直接访问容器
  • 使用服务器进行身份验证

直接访问容器

您可以完全绕过与容器的 SSH 连接,但仍然像 SSH连接到容器一样(使用容器中的用户名和~/.ssh/authorized_keys文件,以及无声"重定向"到容器中,而无需直接访问服务器(。我将假设用户同时存在于服务器和容器中,并且用户名匹配。我们将在此处调用用户ssh_username

在服务器上,您将在容器中docker exec一个 shell(而不是 SSH 到容器中(。将服务器上ssh_username的外壳设置为如下所示:

/usr/local/bin/docker-shell

#!/bin/sh
/usr/bin/docker exec -it -u ${USER} --env SSH_ORIGINAL_COMMAND="${SSH_ORIGINAL_COMMAND}" container_name sh "${@}"

要创建它,您需要执行以下操作:

cat <<"EOF" | sudo tee /usr/local/bin/docker-shell > /dev/null
#!/bin/sh
/usr/bin/docker exec -it -u ${USER} --env SSH_ORIGINAL_COMMAND="${SSH_ORIGINAL_COMMAND}" container_name sh "${@}"
EOF
sudo chmod a+rx /usr/local/bin/docker-shell

服务器身份验证

由于我们不使用密码,也不希望用户在服务器上有 shell,因此我们可以像这样创建用户:

useradd -M -s /usr/local/bin/docker-shell -N -g nogroup ssh_username
mkdir /home/ssh_username
chown ssh_username /home/ssh_username

(使用-M防止在主目录中创建默认文件,-N防止创建匹配的组(

现在,您需要对服务器(而不是容器(进行ssh_username身份验证,但我们不希望必须在两个位置维护authorized_keys文件。我们将使用 SSH 的AuthorizedKeysCommand从 Docker 容器中获取它们。

下面介绍了如何在服务器上配置AuthorizedKeysCommand。编辑服务器的/etc/ssh/sshd_config文件以添加:

Match User ssh_username
AuthorizedKeysCommandUser some_server_user_with_docker_access
AuthorizedKeysCommand /usr/bin/docker exec -i cat /home/ssh_username/.ssh/authorized_keys

some_server_user_with_docker_access将替换为serverdocker组中的用户,因为该用户需要能够在服务器上运行docker exec。这也可能是ssh_username,但随后您需要将该用户添加到docker组,并且您可能不想这样做。

相关内容

  • 没有找到相关文章