章节 ▾ 第二版

4.6 服务器上的 Git - 智能 HTTP

智能 HTTP

我们已经有了通过 SSH 的认证访问和通过 git:// 的未认证访问,但还有一种协议可以同时实现这两种功能。设置智能 HTTP (Smart HTTP) 基本上只需在服务器上启用 Git 自带的一个名为 git-http-backend 的 CGI 脚本。该 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-http-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