权限管理器 Gitosis
权限管理器 Gitosis
把所有用户的公钥保存在
authorized_keys文件的做法只能暂时奏效。当用户数量到了几百人的时候,它会变成一种痛苦。每一次都必须进入服务器的 shell,而且缺少对连接的限制——文件里的每个人都对所有项目拥有读写权限。现在,是时候向广泛使用的软件 Gitosis 求救了。Gitosis 简单的说就是一套用来管理
authorized_keys文件和实现简单连接限制的脚本。最有意思的是,该软件用来添加用户和设定权限的界面不是网页,而是一个特殊的 Git 仓库。你只需要设定好某个项目;然后推送,Gitosis 就会随之改变服务器设定,酷吧?Gitosis 的安装算不上傻瓜化,不过也不算太难。用 Linux 服务器架设起来最简单——以下例子中的服务器使用 Ubuntu 8.10 系统。
Gitosis 需要使用部分 Python 工具,所以首先要安装 Python 的 setuptools 包,在 Ubuntu 中名为 python-setuptools:
$ apt-get install python-setuptools接下来,从项目主页克隆和安装 Gitosis:
$ git clone git://eagain.net/gitosis.git $ cd gitosis $ sudo python setup.py install这会安装几个 Gitosis 用的可执行文件。现在,Gitosis 想把它的仓库放在
/home/git,倒也可以。不过我们的仓库已经建立在/opt/git了,这时可以创建一个文件连接,而不用从头开始重新配置:$ ln -s /opt/git /home/git/repositoriesGitosis 将为我们管理公钥,所以当前的文件需要删除,以后再重新添加公钥,并且让 Gitosis 自动控制
authorized_keys文件。现在,把authorized_keys文件移走:$ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak然后恢复 ‘git’ 用户的 shell,假设之前把它改成了
git-shell命令。其他人仍然不能通过它来登录系统,不过这次有 Gitosis 帮我们实现。所以现在把/etc/passwd文件的这一行git:x:1000:1000::/home/git:/usr/bin/git-shell恢复成:
git:x:1000:1000::/home/git:/bin/sh现在就可以初始化 Gitosis 了。需要通过自己的公钥来运行
gitosis-init。如果公钥不在服务器上,则必须复制一份:$ sudo -H -u git gitosis-init < /tmp/id_dsa.pub Initialized empty Git repository in /opt/git/gitosis-admin.git/ Reinitialized existing Git repository in /opt/git/gitosis-admin.git/这样该公钥的拥有者就能修改包含着 Gitosis 设置的那个 Git 仓库了。然后手动将这个新的控制仓库中的
post-update脚本加上执行权限。$ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update万事俱备了。如果设定过程没出什么差错,现在可以试一下用初始化 Gitosis 公钥的拥有者身份 SSH 进服务器。看到的结果应该和下面类似:
$ ssh git@gitserver PTY allocation request failed on channel 0 fatal: unrecognized command 'gitosis-serve schacon@quaternion' Connection to gitserver closed.说明 Gitosis 认出了该用户的身份,但由于没有运行任何 Git 命令所以它切断了连接。所以,现在运行一个确切的 Git 命令——克隆 Gitosis 的控制仓库:
# 在自己的电脑上 $ git clone git@gitserver:gitosis-admin.git得到一个名为
gitosis-admin的目录,主要由两部分组成:$ cd gitosis-admin $ find . ./gitosis.conf ./keydir ./keydir/scott.pub
gitosis.conf文件是用来设置用户、仓库和权限的控制文件。keydir目录则是保存所有具有访问权限用户公钥的地方——每人一个。你keydir中的文件名(前例中的scott.pub)应该有所不同—— Gitosis 从使用gitosis-init脚本导入的公钥尾部的描述中获取该名。看一下
gitosis.conf的内容,它应该只包含与刚刚克隆的gitosis-admin相关的信息:$ cat gitosis.conf [gitosis] [group gitosis-admin] writable = gitosis-admin members = scott它显示用户
scott——初始化 Gitosis 公钥的拥有者——是唯一能访问gitosis-admin项目的人。现在我们添加一个新的项目。我们将添加一个名为
mobile的新节段,在这里罗列手机开发团队的开发者以及他们需要访问权限的项目。由于 ‘scott’ 是系统中的唯一用户,我们把它加成唯一的用户,从创建一个叫做iphone_project的新项目开始:[group mobile] writable = iphone_project members = scott一旦修改了
gitosis-admin项目的内容,只有提交并推送至服务器才能使之生效:$ git commit -am 'add iphone_project and mobile group' [master]: created 8962da8: "changed name" 1 files changed, 4 insertions(+), 0 deletions(-) $ git push Counting objects: 5, done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 272 bytes, done. Total 3 (delta 1), reused 0 (delta 0) To git@gitserver:/opt/git/gitosis-admin.git fb27aec..8962da8 master -> master第一次向新工程
iphone_project的推送需要在本地的版本中把服务器添加为一个 remote 然后推送。从此手动为新项目在服务器上创建纯仓库的麻烦就是历史了—— Gitosis 会在第一次遇到推送的时候自动创建它们:$ git remote add origin git@gitserver:iphone_project.git $ git push origin master Initialized empty Git repository in /opt/git/iphone_project.git/ Counting objects: 3, done. Writing objects: 100% (3/3), 230 bytes, done. Total 3 (delta 0), reused 0 (delta 0) To git@gitserver:iphone_project.git * [new branch] master -> master注意到路径被忽略了(加上它反而没用),只有一个冒号加项目的名字—— Gitosis 会为你找到项目的位置。
要和朋友们共同在一个项目上共同工作,就得重新添加他们的公钥。不过这次不用在服务器上一个一个手动添加到
~/.ssh/authorized_keys文件末端,而是在keydir目录为每一个公钥添加一个文件。文件的命名将决定在gitosis.conf文件中用户的称呼。现在我们为 John,Josie 和 Jessica 添加公钥:$ cp /tmp/id_rsa.john.pub keydir/john.pub $ cp /tmp/id_rsa.josie.pub keydir/josie.pub $ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub然后把他们都加进 ‘mobile’ 团队,让他们对
iphone_project具有读写权限:[group mobile] writable = iphone_project members = scott john josie jessica如果你提交并推送这个修改,四个用户将同时具有该项目的读写权限。
Gitosis 也具有简单的访问控制功能。如果想让 John 只有读权限,可以这样做:
[group mobile] writable = iphone_project members = scott josie jessica [group mobile_ro] readonly = iphone_project members = john现在 John 可以克隆和获取更新,但 Gitosis 不会允许他向项目推送任何内容。这样的组可以有尽可能有随意多个,每一个包含不同的用户和项目。甚至可以指定某个组为成员,来继承它所有的成员。
如果出现了什么问题,把
loglevel=DEBUG加入到[gitosis]部分或许有帮助(译注:把日志设置到调试级别,记录更详细的信息)。如果你一不小心搞错了配置,失去了推送权限,可以手动修改服务器上的/home/git/.gitosis文件—— Gitosis 从该文件读取信息。一次推送会把gitosis.conf保存在服务器上。如果你手动编辑该文件,它将在你下次向gitosis-admin推送之前它将保持原样。

