Git详解之四 服务器上的Git(第二部分)

4.7  Gitosis

       把全部用户的公钥保存在 authorized_keys 文件的作法,只能凑和一阵子,当用户数量达到几百人的规模时,管理起来就会十分痛苦。每次改删用户都必须登陆服务器不去说,这种作法还缺乏必要的权限管理 — 每一个人都对全部项目拥有完整的读写权限。python

       幸亏咱们还能够选择应用普遍的 Gitosis 项目。简单地说,Gitosis 就是一套用来管理 authorized_keys 文件和实现简单链接限制的脚本。有趣的是,用来添加用户和设定权限的并不是经过网页程序,而只是管理一个特殊的 Git 仓库。你只须要在这个特殊仓库内作好相应的设定,而后推送到服务器上,Gitosis 就会随之改变运行策略,听起来就很酷,对吧?git

      Gitosis 的安装算不上傻瓜化,但也不算太难。用 Linux 服务器架设起来最简单 — 如下例子中,咱们使用装有 Ubuntu 8.10 系统的服务器。web

      Gitosis 的工做依赖于某些 Python 工具,因此首先要安装 Python 的 setuptools 包,在 Ubuntu 上称为 python-setuptools:shell

$ apt-get install python-setuptools

接下来,从 Gitosis 项目主页克隆并安装:
安全

$ git clone git://eagain.net/gitosis.git 
$ cd gitosis 
$ sudo python setup.py install

      这会安装几个供 Gitosis 使用的工具。默认 Gitosis 会把 /home/git 做为存储全部 Git 仓库的根目录,这没什么很差,不过咱们以前已经把项目仓库都放在/opt/git 里面了,因此为方便起见,咱们能够作一个符号链接,直接划转过去,而没必要从新配置:服务器

$ ln -s /opt/git /home/git/repositories

Gitosis 将会帮咱们管理用户公钥,因此先把当前控制文件更名备份,以便稍后从新添加,准备好让 Gitosis 自动管理authorized_keys 文件:ssh

$ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak

接下来,若是以前把 git 用户的登陆 shell 改成 git-shell 命令的话,先恢复 ‘git’ 用户的登陆 shell。改过以后,你们仍然没法经过该账号登陆(译注:由于authorized_keys 文件已经没有了。),不过不用担忧,这会交给 Gitosis 来实现。因此如今先打开 /etc/passwd 文件,把这行:iphone

git:x:1000:1000::/home/git:/usr/bin/git-shell

改回:工具

git:x:1000:1000::/home/git:/bin/sh

好了,如今能够初始化 Gitosis 了。你能够用本身的公钥执行 gitosis-init 命令,要是公钥不在服务器上,先临时复制一份:post

$ sudo -H -u git gitosis-init < /tmp/id_dsa.pub 
Initialized empty Git repository in /opt/git/gitosis-admin.git/ Reinitialize

这样该公钥的拥有者就能修改用于配置 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'

说明 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 insertion

在新工程 iphone_project 里首次推送数据到服务器前,得先设定该服务器地址为远程仓库。但你不用事先到服务器上手工建立该项目的裸仓库— Gitosis 会在第一次遇到推送时自动建立:

$ git remote add origin git@gitserver:iphone_project.git 
$ git push origin master 
Initialized empty Git repository in /opt/gi

请注意,这里不用指明完整路径(实际上,若是加上反而没用),只须要一个冒号加项目名字便可 — 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/je

而后把他们都加进 ‘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 不会容许他向项目推送任何内容。像这样的组能够随意建立,多少不限,每一个均可以包含若干不一样的用户和项目。甚至还能够指定某个组为成员之一(在组名前加上@ 前缀),自动继承该组的成员:

[group mobile_committers] members = scott josie jessica 
[group mobile] writable = iphone_project members = @mobile_committers

若是遇到意外问题,试试看把 loglevel=DEBUG 加到 [gitosis] 的段落(译注:把日志设置为调试级别,记录更详细的运行信息。)。若是一不当心搞错了配置,失去了推送权限,也能够手工修改服务器上的/home/git/.gitosis.conf 文件 — Gitosis 实际是从该文件读取信息的。它在获得推送数据时,会把新的 gitosis.conf 存到该路径上。因此若是你手工编辑该文件的话,它会一直保持到下次向 gitosis-admin 推送新版本的配置内容为止。

4.8  Git 守护进程

对于提供公共的,非受权的只读访问,咱们能够抛弃 HTTP 协议,改用 Git 本身的协议,这主要是出于性能和速度的考虑。Git 协议远比 HTTP 协议高效,于是访问速度也快,因此它能节省不少用户的时间。

重申一下,这一点只适用于非受权的只读访问。若是建在防火墙以外的服务器上,那么它所提供的服务应该只是那些公开的只读项目。若是是在防火墙以内的 服务器上,可用于支撑大量参与人员或自动系统(用于持续集成或编译的主机)只读访问的项目,这样能够省去逐一配置 SSH 公钥的麻烦。

但无论哪一种情形,Git 协议的配置设定都很简单。基本上,只要以守护进程的形式运行该命令便可:

git daemon --reuseaddr --base-path=/opt/git/ /opt/git/

        这里的 --reuseaddr 选项表示在重启服务前,不等以前的链接超时就当即重启。而 --base-path 选项则容许克隆项目时没必要给出完整路径。最后面的路径告诉 Git 守护进程容许开放给用户访问的仓库目录。假若有防火墙,则须要为该主机的 9418 端口设置为容许通讯。

以守护进程的形式运行该进程的方法有不少,但主要还得看用的是什么操做系统。在 Ubuntu 主机上,能够用 Upstart 脚本达成。编辑该文件:

/etc/event.d/local-git-daemon

加入如下内容:

start on startup stop on shutdown exec /usr/bin/git daemon \ --user=git --group=git \ --reuseaddr \ --base-path=/opt/git/ \ /

出于安全考虑,强烈建议用一个对仓库只有读取权限的用户身份来运行该进程 — 只须要简单地新建一个名为 git-ro 的用户(译注:新建用户默认对仓库文件不具有写权限,但这取决于仓库目录的权限设定。务必确认git-ro 对仓库只能读不能写。),并用它的身份来启动进程。这里为了简化,后面咱们仍是用以前运行 Gitosis 的用户 ‘git’。

这样一来,当你重启计算机时,Git 进程也会自动启动。要是进程意外退出或者被杀掉,也会自行重启。在设置完成后,不重启计算机就启动该守护进程,能够运行:

initctl start local-git-daemon

而在其余操做系统上,能够用 xinetd,或者 sysvinit 系统的脚本,或者其余相似的脚本 — 只要能让那个命令变为守护进程并可监控。

接下来,咱们必须告诉 Gitosis 哪些仓库容许经过 Git 协议进行匿名只读访问。若是每一个仓库都设有各自的段落,能够分别指定是否容许 Git 进程开放给用户匿名读取。好比容许经过 Git 协议访问 iphone_project,能够把下面两行加到gitosis.conf 文件的末尾:

[repo iphone_project] daemon = yes

在提交和推送完成后,运行中的 Git 守护进程就会响应来自 9418 端口对该项目的访问请求。

若是不考虑 Gitosis,单单起了 Git 守护进程的话,就必须到每个容许匿名只读访问的仓库目录内,建立一个特殊名称的空文件做为标志:

$ cd /path/to/project.git 
$ touch git-daemon-export-ok

该文件的存在,代表容许 Git 守护进程开放对该项目的匿名只读访问。

Gitosis 还能设定哪些项目容许放在 GitWeb 上显示。先打开 GitWeb 的配置文件 /etc/gitweb.conf,添加如下四行:

$projects_list = "/home/git/gitosis/projects.list"; 
$projectroot = "/home/git/repositories"; $export_ok = "git-daemon-export

接下来,只要配置各个项目在 Gitosis 中的 gitweb 参数,便能达成是否容许 GitWeb 用户浏览该项目。好比,要让 iphone_project 项目在 GitWeb 里出现,把repo 的设定改为下面的样子:

[repo iphone_project] daemon = yes gitweb = yes

在提交并推送过以后,GitWeb 就会自动开始显示 iphone_project 项目的细节和历史。

相关文章
相关标签/搜索