像gitolite这样的程序是如何工作的?

13

我很好奇像gitolite这样的程序是如何工作的 -- 具体来说,它们如何与SSH协议交互以提供定制化的体验。 有人可以举个例子,告诉我如何实现类似以下内容的操作,并在哪里学习更多相关主题?

→ ssh git@github.com
PTY allocation request failed on channel 0
Hi <username>! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

一个旁问:我的主要语言是JavaScript。使用NodeJS可以实现我想要的吗?


2
gitolite 是开源的,你可以通过阅读代码/文档来学习它的工作原理。 - tpg2114
我已经阅读了代码,据我所知它是一个Perl脚本。我不懂Perl,所以希望有人能够提供一个快速的示例来生成我上面所述的内容。 - user1813844
https://dev59.com/Hm435IYBdhLWcg3w1z4t - Peter Oram
3个回答

28

gitolite本身是一个授权层,不需要使用ssh。
它只需要知道在调用它,以便授权或拒绝该人执行git命令。

SSH用于身份验证(但您也可以使用Http Apache进行身份验证,例如)

Gitolite由ssh调用的方式在“Gitolite和ssh”中有详细解释,并使用ssh机制强制命令

http://oreilly.com/catalog/sshtdg/chapter/ssh_0802.gif

"

~/.ssh/authorized_keys(位于 gitolite ssh 服务器上)的样子如下:

"
command="[path]/gitolite-shell sitaram",[more options] ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA18S2t...
command="[path]/gitolite-shell usertwo",[more options] ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArXtCT...

首先,它会查找此文件中哪些公钥与登录信息匹配。一旦找到匹配项,它将在该行上运行给定的命令;例如,如果我登录,它将运行[path]/gitolite-shell sitaram。因此,需要注意的第一件事是这些用户没有"shell访问权限",这是很好的!(强制命令=无交互式shell会话:它只提供一个受限shell,执行一个脚本,总是相同的)。
然而,在运行命令之前,sshd会设置一个名为SSH_ORIGINAL_COMMAND的环境变量,其中包含您的工作站发送的实际git命令。
这是如果您在授权密钥文件中没有command=部分将要运行的命令。 当gitolite-shell接管时,它查看第一个参数("sitaram","usertwo"等)以确定您是谁。 然后,它查看SSH_ORIGINAL_COMMAND变量以找出您想要访问哪个存储库以及您是读取还是写入。 现在,它已经拥有了用户、存储库和请求的访问权限(读/写),gitolite会查看其配置文件,然后允许或拒绝该请求。
由于Gitolite是用Perl编写的,所以authorized_keys调用了一个Perl脚本(gitolite-shell)。它同样可以调用JavaScript程序。
如果你在GitHub上的ssh没有任何命令,你会收到一个问候消息,就像你在问题中提到的那样。
Gitolite 也会显示类似的消息,详见info命令脚本的print_version()函数
sub print_version {
    chomp( my $hn = `hostname -s 2>/dev/null || hostname` );
    my $gv = substr( `git --version`, 12 );
    $ENV{GL_USER} or _die "GL_USER not set";
    print "hello $ENV{GL_USER}, this is " . ($ENV{USER} || "httpd") . "\@$hn running gitolite3 " . version() . " on git $gv\n";
}

消息看起来像:

hello admin, this is git@server running gitolite3 v3.0-12-ge0ed141 on git 1.7.3.4

2013年底的Gitolite文档现在包括了那个总结所有部分的图表:

ssh and Gitolite


只是出于好奇,像GitHub这样的网站如何利用这些技术?维护一个包含每个人公钥的git用户的authorized_keys文件以及处理该文件的更改(删除密钥等)似乎不切实际? - user1813844
@user1813844 GitHub?但是GitHub肯定不会使用gitolite。它有自己的ssh密钥管理。我想这与Gitolite使用的ssh密钥管理一样实用。 - VonC
那么他们有自己的SSHD版本吗?我正在尝试弄清楚他们如何使用标准现有技术构建他们的系统。 - user1813844
只允许使用 git-upload-pack 和 git-receive-pack 等命令,其他类似于 ls、rm 的 unix 命令被禁止。 - linquize
1
@linquize 正确,我在 http://stackoverflow.com/a/11646767/6309 中也提到了。使用 V3,您还可以运行一小组 gitolite 命令:http://sitaramc.github.com/gitolite/cust.html#commands - VonC
显示剩余5条评论

5

注意,sshd会对~/.ssh/authorized_keys文件进行线性扫描。一旦您在该文件中拥有约3000个密钥,那么出现在文件末尾的密钥所属的用户将开始注意到延迟-这种延迟已经超过了网络延迟:-)

这是 Github 拥有自己修改版本的 sshd 的原因之一。他们拥有太多的用户,无法使用正常的 sshd 进行管理!


0

基本步骤如下:

  1. 检查尝试登录的人的公钥
  2. 将公钥映射到访问控制列表中

换句话说,为了使这些事情起作用,您必须从用户那里获取公钥,然后生成一个列表(文件、数据库或其他)将密钥与用户和权限配对。


我更感兴趣的是使用SSH协议的机制。 - user1813844
如何在登录后限制SSH用户仅使用预定义的一组命令?然后让您的问题更清晰。我查看了gitolite源文件顶部的注释,它说“从~/.ssh/authorized_keys调用脚本”,所以我搜索了如何从authorized_keys文件中调用脚本并找到了那个问题。 - tpg2114
我并不是在这里故意捣乱。但是当问题看起来没有花费太多努力独立解决时,我也不太愿意详细回答并提供大量细节。 - tpg2114

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接