为啥不需要在 Docker 容器中运行 sshd

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥不需要在 Docker 容器中运行 sshd相关的知识,希望对你有一定的参考价值。

可能你还没有理解docker的概念,他是容器,不是一个系统,不必非要有sshd服务来进行用户登录。我只要满足我需求的container就可以了。比如我只想要一个运行java环境的docker,那么这个docker只要可以运行java代码就可以了,其他的服务根本就不需要。 参考技术A

    Docker容器运行后,如何进入容器进行操作呢?起初我是用SSH。如果只启动一个容器,用SSH还能应付,只需要将容器的22端口映射到本机的一个端口即可。当我启动了五个容器后,每个容器默认是没有配置SSH Server的,安装配置SSHD,映射容器SSH端口

让 git 用户的 sshd 登录转发到(GitLab)Docker 容器

【中文标题】让 git 用户的 sshd 登录转发到(GitLab)Docker 容器【英文标题】:Have sshd forward logins of git user to a (GitLab) Docker container 【发布时间】:2016-01-07 16:06:15 【问题描述】:

我想在我的主机上配置 sshd,以将某个用户的公钥登录转发到运行自己的 sshd 服务的 Docker 容器。

为了提供一些上下文,我在 Docker 容器中运行 GitLab,我不喜欢在主机上打开另一个端口以进行 SSH GitLab 通信,而是在主机上使用 sshd 重定向用户并直接键入 GitLab 公开的端口在本地机器上。

我的想法是做这样的事情:

Match User git
  ForceCommand ssh -p <GitLab port> <some arguments that forward to> git@localhost
  ...

非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

我正在尝试将我的 git 存储库通过我的主机推送到 docker 机器中。 我玩了一点 ForceCommand 选项。 这对我有用;)

Match User git
  ForceCommand ssh git@localhost -p 9022 $SSH_ORIGINAL_COMMAND

【讨论】:

试过这个,没用。您是在 Docker 主机端的 SSHD 中执行此操作……还是在客户端(本地存储库所在的位置)? 此方法不起作用,因为它不会将公钥转发到在端口 9022 上运行的 ssh 服务器。 这可行,但有一个问题:您需要在客户端 .ssh/config 文件中添加“ForwardAgent yes”。【参考方案2】:

我找到了一个简单的解决方法。只需在主机上创建一个 Git 用户并提供一个代理脚本,该脚本使用主机的 SSH 守护程序和容器卷中的 .ssh/authorized_keys 在 GitLab 容器中执行给定的 Git 命令。

    在主机上,使用与 GitLab docker 容器 (998) 中相同的 UID 和 GID 添加用户 git,并将 GitLab data 目录设置为用户的主目录:

    useradd -u 998 -s /bin/bash -d /your/gitlab/path/data git
    

    git用户添加到docker组

    usermod -G docker git
    

    在宿主机上添加代理脚本/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell,内容如下:

    #!/bin/bash
    docker exec -i -u git <your_gitlab_container_id> sh -c "SSH_CONNECTION='$SSH_CONNECTION' SSH_ORIGINAL_COMMAND='$SSH_ORIGINAL_COMMAND' $0 $1"
    

【讨论】:

我在 docker run 命令中添加了--env="USERMAP_UID=$((id git -u)) --env="USERMAP_GID=$((id git -g))" 以避免使用奇怪的 uid/gid(我添加了经典用户,没有 -u 998) 您需要使用docker exec -i -u git &lt;gitlab_container&gt; sh -c ... 否则git存储库将被访问(和修改)为root。这实际上会起作用,但最终您会遇到问题(例如,当您尝试使用 Gitlab Web 界面编辑存储库中的文件时)。 GitLab 数据目录是什么意思? /var/opt/gitlab ? 这个解决方案的缺点是hosts“git”用户在docker组中,从安全角度来看是有问题的。 我想试试这个,但我首先想了解第三步。你能详细说明它的作用吗?这么多年过去了,它还能正常工作吗?在我的系统中,我拥有的最近路径是/opt/gitlab/data/gitlab-shell/,其中没有bin 目录。【参考方案3】:

另一种(未经测试的)可能性可能是您将连接从主机转发到容器,方法是将其添加到 git 用户的 authorized_keys 文件中:

command="nc -q0 gitlab 22" ssh-rsa AAAAB....[REST OF YOUR PUBKEY]

应该在主机上创建 git 用户。现在当你用“ssh git@host”连接时,这个连接应该用“nc”转发到gitlab容器。

显然,这还需要将所有带有 command 前缀的 gitlab ssh 密钥复制到主机

但是,这只有在 gitlab 容器不在处于隔离网络中并且主机容器实际上有可能连接到 gitlab 端口 22 时才有效。

在我的设置中,这不起作用,因为 gitlab 处于隔离网络中,所以我最终在另一个端口上运行 gitlab ssh:

-p 20022:22启动容器 将gitlab_rails['gitlab_shell_ssh_port'] = 20022 添加到您的 gitlab.rb 配置中

【讨论】:

这看起来很有希望——但是当我尝试它时,git 接收到 SSH 协议数据而不是它所期望的。【参考方案4】:

您的提议将使用户需要进行两次身份验证。一次使用您的服务器,第二次使用 docker 中的 gitlab,这基本上是您不想要的。

当您提到公钥身份验证时,它需要以某种方式与您的主机共享来自您的 gitlab 的授权密钥文件或命令。

我相信这是可能的,但是打开那个端口要容易得多。

从客户端,您可以像这样对ProxyCommand 执行相同的操作:

Hostname your-gitlab
  ProxyCommand ssh -W localhost:<GitLab port> git@your-git-host

【讨论】:

我想知道 git 是否可以使用它。你知道.. gitlab 提供 git 托管。我真的想知道这是否可行:git clone your-gitlab:foo/bar.git @GottZ 为什么不呢?你有没有尝试过?这是多跳路由的常见做法。 @Jakuje,您可能是对的:这将导致两次身份验证。我可以忍受,但我没有看到共享授权密钥文件的简单方法。公认。 :)

以上是关于为啥不需要在 Docker 容器中运行 sshd的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 udev 规则在运行的 docker 容器中不起作用?

为啥 Docker 容器正在运行但 localhost 只显示“它有效”? [关闭]

k8s和docker区别

大项目docker打包部署慢

为啥 Kubernetes 的容器在 runsc (gVisor) 上作为 Docker 中的运行时运行时会失败?

为啥docker容器立即退出