把所有用户的公钥保存在 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/repositories
Gitosis 将为我们管理公钥,所以当前的文件需要删除,以后再重新添加公钥,并且让 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:repositories/gitosis-admin.git
#因为gitosis暂时并没有我work,所以实际上只能使用ssh+实际文件路径来寻址。
一但服务配置好了, 那么就可以使用git clone git@server:repos.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
这里要特别注意,一定要拷贝好pub之后,修改gitosis.conf里访问权限。比方说如果刚开始使用sshclone的,那么你一定要在第一次push之前为gitosis-admin增加你的访问权限。 否则,你无法读写gitosis-admin,更没法管理了。 解决办法也有:登录/home/git/.ssh . 删除authorizth_keys里关于你的pub片段,重新ssh方式git clone. 修改gitosis.conf之后,在push,这样,你就可以使用git clone git@server:gitosis.git重新写clone. 现在你就可以不用密码来管理gitosis.conf了。
gitosis使用push来管理用户,以及repos,操作简单,只需要修改gitosis.conf即可。 同时,吧pub文件放在合适的位置。
红色字体部分是个人心得
一旦修改了 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 推送之前它将保持原样。
另外一点需要注意,当再keydir里添加自己的pub时,一定要以.pub结尾。
|