我有一个Raspberry Pi,我用它作为Git服务器。有多个物理用户访问它,目前每个用户在服务器上都有自己的登录。换句话说,用户John和Doe可以通过运行ssh john@server.com
或doe@server.com
来使用SSH登录服务器。
物理用户拥有私有Git存储库,其他用户无法访问。例如。 John的回购位于/home/john/repos
,Doe的回购位于服务器上的/home/doe/repos
。
我想要的只是一个名为git
的用户,它控制所有用户的回购。例如,他将使用john@server.com:repos/project.git
而不是John拥有远程git@server.com:john/project.git
。同样,Doe会推送到git@server.com:doe/some_other_project.git
如何在确保人们无法访问彼此的回购的同时实现这一目标?服务器通过SSH访问。
答案 0 :(得分:0)
最简单的解决方案是设置像gitlab这样的东西,它提供了一个Web界面,各种访问控制,以及各种其他的花里胡哨。
如果你真的想自己动手:
从directions in the Git book开始,设置服务器以允许通过ssh访问共享用户。
这些说明将为您提供一个共享的git
帐户,每个人都可以访问该帐户,并允许任何人从任何存储库推送/提取。我们可以实现一个简单的授权层,将用户限制在特定目录中的存储库。
从一个小包装脚本开始:
#!/bin/sh
repo_prefix=$1
eval set -- $SSH_ORIGINAL_COMMAND
case "$1" in
(git-receive-pack|git-upload-pack|git-upload-archive)
# prevent attempts at using dir/../path to escape
# repository directory
case "$2" in
(*..*) echo "Invalid repository name." >&2
exit 1
;;
esac
repo_path="$repo_prefix/$2"
eval exec $1 $repo_path
;;
(*) echo "Unsupported command" >&2
exit 1
;;
esac
这将为所有存储库路径添加前缀路径(作为命令行参数提供)。现在,我们需要安排这个包装器来拦截git操作。
要使用此功能,您需要修改添加到git
用户authorized_keys
文件的公钥。如果您按照Git书中的说明操作,authorized_keys
文件中将包含一个或多个公钥,如下所示:
ssh-rsa AAAA...== some comment
对于每个公钥,您将需要添加一个配置选项,该选项将导致调用包装器脚本来代替原始命令。从sshd
手册页:
文件的每一行都包含一个键(空行和行开头) 用'#'作为注释被忽略)。协议1公钥包括 以下以空格分隔的字段:options,bits,exponent, 模数,评论。协议2公钥包括:options,keytype, base64编码的密钥,评论。选项字段是可选的......
稍微向下:
支持以下选项规范(请注意该选项 关键字不区分大小写):[...]
<强>命令=&#34;命令&#34; 强>
指定在使用此密钥时执行命令 认证。用户提供的命令(如果有)是 忽略...客户端最初提供的命令可用 在SSH_ORIGINAL_COMMAND环境变量中。
考虑到这一点,我们修改我们的authorized_keys
文件,看起来像这样:
command="/usr/bin/git-wrapper.sh username" ssh-rsa AAAA...===
这意味着当有人使用相应的私钥连接时,sshd
将运行git-wrapper.sh username
,导致我们的git-wrapper.sh
脚本在字符串username
前面添加存储库路径,确保git
只会看到给定目录中的存储库。更具体地说,当你运行:
git push origin master
假设origin
指向git服务器上的project.git
,那么git
将尝试在远程服务器上运行命令:
git-receive-pack project.git
我们的包装器脚本将拦截它,并将其转换为:
git-receive-pack $1/project.git
例如,如果我们的git git
用户主目录没有存储库:
git$ ls
我们的authorized_keys
文件如下所示:
git$ cat .ssh/authorized_keys
command="/usr/bin/git-wrapper.sh alice" ssh-rsa ... alice@example.com
command="/usr/bin/git-wrapper.sh bob" ssh-rsa ... bob@example.com
然后如果alice
执行此操作:
alice$ git remote add origin git@mygitserver:project.git
git push origin master
她会看到:
fatal: 'alice/project.git' does not appear to be a git repository
fatal: Could not read from remote repository.
如果我们创建目标存储库:
git$ mkdir alice
git$ git init --bare alice/project.git
然后她可以推动:
alice$ git push origin master
[...]
To git@mygitserver:project.git
* [new branch] master -> master
但是如果bob试图克隆该存储库:
bob$ git clone git@mygitserver:project.git
它会失败:
fatal: 'bob/project.git' does not appear to be a git repository
fatal: Could not read from remote repository.
即使他尝试偷偷摸摸的东西:
bob$ git clone git@mygitserver:../alice/project.git
Invalid repository name
fatal: Could not read from remote repository.
而且,有点冗长的说法,就是如何访问git存储库服务器的授权。请注意,这只是为了演示目的而完成 ;您希望在生产环境中使用更强大的脚本。