正如您在标题中读到的那样,我目前正在运行多个用作 git 服务器的 docker 容器,通常应该在端口 22 下运行。这显然不起作用,但我的要求如下。
在端口 22 上提供以下内容:
- git@HOST-重定向到 gitlab docker 容器
- bitbucket@HOST-重定向到 bitbucket 容器
- root@HOST-(我根本没有以 root 身份工作,但出于理解的原因)以正常的 SSH 身份访问 Docker Mainhost。
我知道我必须在容器和账户之间同步 ssh 密钥,但这不是一个大问题,但我不知道是否有可能构建一个重定向系统。
我的一种方法是使用部队指挥但我无法重定向使用的 SSH 密钥...
另一个想法是在端口 22 上运行一个小工具,它只在所有 SSH 守护进程之间路由完整的请求,但我还没有(还没有?)找到这样的工具,并且不知道是否可以出于安全原因构建这样的工具。
答案1
我认为您实际上并不需要“重定向使用的 ssh 密钥”,您可以为每个拥有其密钥作为 authorized_keys 的用户创建一个密钥/证书,然后您可以ssh -i $key $final_destination
通过 ForceCommand 使用。
如果您使用,AuthorizedKeysCommand
您可以查询公钥的中央存储库,这将返回两行 - 一行用于真实用户的公共 ssh 密钥,第二行用于“内部公共 ssh 密钥”,您可以用注释区分这两行,并根据您从哪个主机执行查询的信息在此存储库中查询密钥。例如,在跳转主机上,您可以过滤具有例如此注释“foouser@”的公钥,在最终目的地,您可以相反地查询带有注释“@internal”的 foouser 的公钥。使用最新的 OpenSSH,您可以在跳转主机上使用ExposeAuthInfo
sshd 选项来了解哪个公共 ssh 密钥被用于登录跳转主机,然后您可以重新查询中央存储库中的密钥并 grep 与 $SSH_USER_AUTH 中的密钥匹配的密钥。这样,就会根据返回的带有公共 ssh 密钥和注释的行知道要使用哪个私钥来 ssh 到最终目的地。
用户实际上并不关心她是如何登录最终主机的,特别是如果它不是一个交互式 shell。
跳转主机和最终目的地上的 AuthorizedKeysCommand:
#!/bin/sh
user=$1 # git !
filter=$2 # @$
cat /home/git/.ssh/authorized_keys 2>/dev/null | grep "${filter:-@$}"
exit 0
跳转主机上的 sshd_config:
ExposeAuthInfo yes
Match User git
AuthorizedKeysCommand /path/to/authorizedkeyscommand git # @$ as default
ForceCommand /path/to/forcecommand git
AuthorizedKeysCommand 可以返回:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILleQxrxxxxxxxxxxxxxxxxxxx foouser@
跳转主机上的 ForceCommand:
#!/bin/ksh
set -x
user=$1 # git
if [[ -r ${SSH_USER_AUTH} ]]; then
pubkey="$(cat ${SSH_USER_AUTH} | cut -d' ' -f2-)"
realuser=$(/path/to/authorizedkeyscommand git | grep "${pubkey}" | sed 's/^.* \([^@]*\)@$/\1/' )
[[ -n ${realuser} ]] && exec ssh -i $HOME/${realuser}_key <final_destination> "${SSH_ORIGINAL_COMMAND:-}"
else
exit 1
fi
像这样...
答案2
有一个当前(2021 年)可行的解决方案作为 Medium 文章发布,用于与 gitlab 容器共享主机 ssh 端口。它也应该适用于 bitbucket 容器。
它使用代理脚本将 git 用户的 ssh 连接转发到 gitlab 容器中。
有趣的部分从标题“为 git 用户转发 SSH(重用端口 22)”开始
https://pezhvak.medium.com/how-to-spin-up-gitlab-on-docker-reusable-host-ports-2cfd220c74b0
答案3
我对在网上找到的所有解决方案都不满意。我最终得到以下解决方案。
我有一个像下面这样运行的 docker 容器docker -v /srv/gitlab/data:/var/opt/gitlab gitlab
。检查 gitlab 目录后,我发现有一个/srv/gitlab/data/.ssh/authorized_keys
文件保存了 ssh 身份验证所需的所有密钥。该文件包含以下内容:
command="/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell key-1",no-port-forwarding,no-.....
最好的办法是使用该文件进行身份验证,在主机上重新使用同一组公钥,然后将命令转发到docker容器内部。
Match User git
X11Forwarding no
AllowTcpForwarding no
PermitTTY no
AuthorizedKeysCommandUser root
AuthorizedKeysCommand /usr/bin/cat /srv/gitlab/data/.ssh/authorized_keys
AuthorizedKeysCommandUser
如果您创建的 git 用户与 docker 容器内部的 UID 相同,则可以将和AuthorizedKeysCommand
替换为。AuthorizedFile
对于 GitLab,git 用户的 UID 为 998。
然后我创建了一个shell脚本/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell
在主机上(遗憾的是)内容如下:
#!/bin/sh
exec docker exec gitlab env SSH_CONNECTION="$SSH_CONNECTION" "$0" "$@"
有趣的是,由于脚本的路径在主机和 docker 容器内是相同的,所以我可以重复使用"$0"
。方法作品,尽管我认为这只是一种解决方法。