![使用 ssh 密钥设置一个没有 root 权限的共享远程 git 存储库(已解决)来管理每个用户的访问?](https://linux22.com/image/1383537/%E4%BD%BF%E7%94%A8%20ssh%20%E5%AF%86%E9%92%A5%E8%AE%BE%E7%BD%AE%E4%B8%80%E4%B8%AA%E6%B2%A1%E6%9C%89%20root%20%E6%9D%83%E9%99%90%E7%9A%84%E5%85%B1%E4%BA%AB%E8%BF%9C%E7%A8%8B%20git%20%E5%AD%98%E5%82%A8%E5%BA%93%EF%BC%88%E5%B7%B2%E8%A7%A3%E5%86%B3%EF%BC%89%E6%9D%A5%E7%AE%A1%E7%90%86%E6%AF%8F%E4%B8%AA%E7%94%A8%E6%88%B7%E7%9A%84%E8%AE%BF%E9%97%AE%EF%BC%9F.png)
我首先解释一下我的设置。我正在一个非自管理系统上工作,在这个系统上我有一个没有 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
这些命令执行以下操作:
- 创建 git 存储库
- 生成 ssh 密钥
- 将密钥添加到 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
这些命令执行以下操作:
- 将 rsa 密钥放在 ~/.ssh 目录中
- 向 ~/.ssh/config 添加一条规则,使用密钥指定主机名 'gitserver'
- 检索存储库内容
使用的命令基于限制仅 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 命令时,存在安全风险。如果命令至少包含一次允许的存储库,它将执行整个命令。有什么改进建议吗?