透明ssh连接转发到docker容器

gijlo24d  于 2023-08-03  发布在  Docker
关注(0)|答案(3)|浏览(156)

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

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。

vfh0ocws

vfh0ocws1#

把它放到~/.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

mm9b1k5b

mm9b1k5b2#

这是我现在想出的解决方案。我对第二个密钥有点不满意,因为它的公共部分将在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,该container具有仅用于该特定auth的专用密钥。我有点担心你可以通过注入一些命令来突破command=,但到目前为止,我没有发现允许突破的排列。
由于传递了$SSH_ORIGINAL_COMMAND,您甚至可以执行scpssh-copy-id等等。
注意:要禁止ssh-copy-id(我出于其他原因想要这样做),只需在容器内为user设置authorized_keys不可写。

ffvjumwh

ffvjumwh3#

这将是两个部分:

  • 直接进入容器
  • 与服务器进行身份验证

直接访问容器

您可以完全绕过到容器的SSH连接,但仍然像SSH正在连接到容器一样(使用用户名和容器中的~/.ssh/authorized_keys文件,并静默“重定向”到容器,而不直接访问服务器)。我将假设用户同时存在于服务器和容器中,并且用户名匹配。我们在这里调用用户ssh_username
在服务器上,您将docker exec容器中的shell(而不是SSHing到容器中)。将服务器上ssh_username的shell设置为如下所示:
/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组,您可能不想这样做。

相关问题