使用 ssh 密钥设置一个没有 root 权限的共享远程 git 存储库(已解决)来管理每个用户的访问?

使用 ssh 密钥设置一个没有 root 权限的共享远程 git 存储库(已解决)来管理每个用户的访问?

我首先解释一下我的设置。我正在一个非自管理系统上工作,在这个系统上我有一个没有 root/提升权限的帐户。在这个系统上,我想将多个 git 存储库共享给不同的人群。实现共享 git 存储库所采取的操作如下。我将它们分为在远程和本地系统上的 bash 终端中执行的命令。ps:用适当的值替换分隔符 < 和 > 包围的任何变量。

----------- 远程(我的系统):-----------

bash-4.2> mkdir -p <path>/<to>/project.git
bash-4.2> cd <path>/<to>/project.git
bash-4.2> git init --bare
bash-4.2> ssh-keygen -t rsa -f ~/.ssh/gitkey_rsa -N <password>
bash-4.2> echo "command=\"git-shell -c \\\"\$SSH_ORIGINAL_COMMAND\\\"\",
    no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty \
    $(cat ~/.ssh/gitkey_rsa.pub)" >> ~/.ssh/authorized_keys

这些命令执行以下操作:

  1. 创建 git 存储库
  2. 生成 ssh 密钥
  3. 将密钥添加到 authorized_keys 中,并附加限制

----------- 本地(其他用户)-----------

bash-4.2> mv <path>/<to>/gitkey_rsa ~/.ssh
bash-4.2> echo -e "Host gitserver\n\
    \tHostName <remote server>\n\
    \tUser <remote user>\n\
    \tIdentityFile ~/.ssh/gitkey_rsa" >> ~/.ssh/config
bash-4.2> git clone gitserver:/home/<remote user>/<path>/<to>/project.git

这些命令执行以下操作:

  1. 将 rsa 密钥放在 ~/.ssh 目录中
  2. 向 ~/.ssh/config 添加一条规则,使用密钥指定主机名 'gitserver'
  3. 检索存储库内容

使用的命令基于限制仅 git 访问。通过使用受限密钥,用户只能执行 git 命令。问题是用户还被允许访问远程系统上的每个 git 存储库。我想限制每个 ssh 密钥只能访问一个存储库。换句话说,我想通过 ssh 密钥限制来限制对包含 git 存储库的一个文件夹的访问。

我到目前为止找到的解决方案是:通过 ssh 仅访问某些目录将 SSH 用户限制在一个文件夹中。他们要么希望您安装 (S)FTP 服务器、WebDAV,要么创建具有受限权限的新用户。这不是我想要的,因为它需要 root 权限。由于可以使用 ssh 密钥限制来限制命令,那么有没有办法也可以限制访问权限呢?

问候

答案1

可能的解决方案

当我输入问题时,我想到了一个解决方案。但在我看来,这个问题一定有一个更简单、更安全的解决方案。我所做的是将 authorized_keys 文件中的“command”值更改为:

command="~/somescript.sh" 

并且“somescript.sh”包含:

#!/bin/bash
ALLOW=(
    '/home/<user>/repository1.git'
    '/home/<user>/repository2.git'
)

case $SSH_ORIGINAL_COMMAND in
    "git-receive-pack"*|"git-upload-pack"*|"git-upload-archive"*)
        GITPATH=$(echo $SSH_ORIGINAL_COMMAND | sed -r "s:.*'([^']*)'.*:\1:g")
        ALLOWED="false"
        for ((i=0; i < ${#ALLOW[@]}; i++)); do
            if [ "${ALLOW[$i]}" == "$GITPATH" ]; then
                ALLOWED="true"; break;
            fi
        done

        if [ "$ALLOWED" == "true" ]; then
            eval "git-shell -c \"$SSH_ORIGINAL_COMMAND\""
        else
            echo "[ERROR] ACCESS DENIED" >&2
            exit 1
        fi
        ;;
    *)
        echo "[ERROR] Only git commands are allowed!" >&2
        exit 1
        ;;
esac

在脚本中我利用了 git clone、git push 和 git pull 命令在远程端生成的特性:

git-upload-pack '<path>/<to>/<repository>', or
git-receive-pack '<path>/<to>/<repository>'

我在变量 ALLOW 中指定允许通过使用脚本的 ssh 密钥访问的存储库,并简单地将它们与发出的 git 命令(变量 GITPATH)中指定的路径进行比较。但是,当在一行中发出多个 git 命令时,存在安全风险。如果命令至少包含一次允许的存储库,它将执行整个命令。有什么改进建议吗?

相关内容