章节 ▾ 第二版

4.6 服务器上的 Git - Smart HTTP

Smart HTTP

现在我们有了通过 SSH 进行身份验证的访问,以及通过 git:// 进行非身份验证的访问,但还有一种协议可以同时实现这两种功能。设置 Smart HTTP 基本上就是启用 Git 提供的一个 CGI 脚本,叫做 git-http-backend 在服务器上。这个 CGI 会读取 git fetchgit push 到 HTTP URL 发送的路径和头部,并确定客户端是否可以通过 HTTP 进行通信(对于 1.6.6 版本以后的任何客户端都适用)。如果 CGI 发现客户端是智能的,它将与客户端进行智能通信;否则它将回退到非智能行为(因此它与旧客户端的读取操作向后兼容)。

我们来走一遍一个非常基本的设置。我们将使用 Apache 作为 CGI 服务器进行设置。如果你没有设置 Apache,你可以在 Linux 机器上使用类似这样的命令进行设置

$ sudo apt-get install apache2 apache2-utils
$ a2enmod cgi alias env

这还会启用 mod_cgimod_aliasmod_env 模块,这些都是使其正常工作所必需的。

你还需要将 /srv/git 目录的 Unix 用户组设置为 www-data,这样你的 Web 服务器才能读写访问仓库,因为运行 CGI 脚本的 Apache 实例将(默认情况下)以该用户身份运行

$ chgrp -R www-data /srv/git

接下来,我们需要在 Apache 配置中添加一些内容,以便将 git-http-backend 作为 Web 服务器 /git 路径下所有请求的处理程序来运行。

SetEnv GIT_PROJECT_ROOT /srv/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

如果你省略 GIT_HTTP_EXPORT_ALL 环境变量,那么 Git 将只向未经身份验证的客户端提供其中包含 git-daemon-export-ok 文件的仓库,就像 Git 守护进程一样。

最后,你需要告诉 Apache 允许对 git-http-backend 的请求,并通过某种方式对写入进行身份验证,可能使用如下的 Auth 块

<Files "git-http-backend">
    AuthType Basic
    AuthName "Git Access"
    AuthUserFile /srv/git/.htpasswd
    Require expr !(%{QUERY_STRING} -strmatch '*service=git-receive-pack*' || %{REQUEST_URI} =~ m#/git-receive-pack$#)
    Require valid-user
</Files>

这将要求你创建一个包含所有有效用户密码的 .htpasswd 文件。以下是向文件中添加“schacon”用户的示例

$ htpasswd -c /srv/git/.htpasswd schacon

Apache 验证用户的方法有很多,你必须选择并实现其中一种。这只是我们能想到的最简单的例子。你几乎肯定也会希望通过 SSL 设置它,这样所有数据都将被加密。

我们不想深入探究 Apache 配置的具体细节,因为你很可能使用不同的服务器或有不同的身份验证需求。其思想是,Git 带有一个名为 git-http-backend 的 CGI,当被调用时,它将完成所有通过 HTTP 发送和接收数据的协商。它本身不实现任何身份验证,但可以通过调用它的 Web 服务器层轻松控制。你可以使用几乎任何支持 CGI 的 Web 服务器来完成此操作,因此请选择你最熟悉的那个。

注意

有关 Apache 中配置身份验证的更多信息,请查看 Apache 文档:https://httpd.apache.ac.cn/docs/current/howto/auth.html