章节 ▾ 第二版

4.6 Git on the Server - Smart HTTP

Smart HTTP

我们现在可以通过 SSH 进行认证访问,并通过 git:// 进行非认证访问,但还有一种协议可以同时完成这两件事。设置 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-daemon-export-ok 文件的仓库提供未认证的客户端访问,就像 Git daemon 一样。

最后,你还需要告诉 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