如何通过 HTTP (s) 设置 Git 服务器¶
您可能已经设置了一个 Git 服务器;这就像在 NIX 机器上启用 SSH 一样简单。
*但您可能遇到过**不那么寻常的情况**,即您在一个随机网络上,**无法访问端口 22!**
本指南介绍了如何使用 Git Smart-HTTP 协议设置 HTTPS Git 服务器。
步骤 1:权限,权限,还是权限!¶
参见:常见问题:为什么我会收到 403 Forbidden 错误?
权限非常重要!请记住 Git 将对目录和文件执行读写操作!请务必正确设置您的用户和组。您可能需要对 Git 仓库执行 chmod
和 chown
操作,以便 Lighttpd 服务器运行的用户/组能够访问它。Lighttpd 在其运行的用户/组下运行 CGI 程序(例如 Git)。(使用辅助程序——例如 execwrap 或 suEXEC ——进行额外配置可以改变这一点,但此处不再进一步讨论)。
步骤 2:依赖和模块¶
对于系统依赖,您将需要(当然)
- git
(请确保您有 /usr/lib/git-core/git-http-backend
二进制文件,这应该在 Arch Linux 上随 Git 软件包默认安装)
对于 Lighttpd 模块,您将需要
- mod_cgi
- mod_alias
- mod_setenv
- mod_auth (可选)以及 mod_authn_file
。
步骤 3:针对特定仓库的最低配置¶
您必须使用子域或完全不同的域,否则 CGI 脚本会混淆,无法正确读取路径。
要使 CGI git-http-backend
脚本正常工作,最低要求是
- 将环境变量 GIT_PROJECT_ROOT
设置为您 Git 仓库之一的父目录。
- 在您希望可访问的每个 Git 仓库中创建一个 git-daemon-export-ok
文件。
server.modules += ("mod_setenv", "mod_cgi", "mod_alias") $HTTP["host"] == "git-test.yourdomain.com" { alias.url = ( "" => "/usr/lib/git-core/git-http-backend" ) setenv.set-environment = ( "GIT_PROJECT_ROOT" => "/var/www/git/" ) cgi.assign = ( "" => "" ) }
上述代码假定
- 您的域名 git-test.yourdomain.com
仅用于此 CGI 脚本。
- /var/www/git/
是一个包含裸 Git 仓库的目录。
- 并且每个仓库(服务器端)都包含一个 git-daemon-export-ok
文件。
步骤 4:添加自动仓库发现¶
好的,您已经有了一个基本配置。现在您希望实现某种自动发现功能,这样就不必手动添加每个 Git 仓库了。您可以通过设置环境变量 GIT_HTTP_EXPORT_ALL
来实现这一点。请记住,在需要追加变量时,应该使用 +=
运算符。参见 mod_setenv
setenv.set-environment += ( "GIT_HTTP_EXPORT_ALL" => "" )
太棒了!现在您可以克隆 /var/www/git/
下的任何仓库了。
步骤 5:通过 HTTP 添加身份验证¶
根据 Git Smart-HTTP 文档,Git 本身不实现任何类型的安全性。这是 Web 服务器(在本例中为 Lighttpd)的工作。我们可以通过添加 HTTP 身份验证来实现安全性。请参阅 mod_auth。以下配置将仅允许经过身份验证的用户从仓库克隆和推送到仓库
# using mod auth with plain text module mod_authn_file
server.modules += ("mod_auth", "mod_authn_file")
server.modules += ("mod_setenv", "mod_cgi", "mod_alias")
$HTTP["host"] == "git-test.yourdomain.com" {
# password file is at /home/www-data/user-info
# example plain-text password file:
# agent007:secret
auth.backend = "plain"
auth.backend.plain.userfile = "/home/www-data/user-info"
# this must be set to require auth under this domain.
auth.require = ( "" => ("method" => "basic", "realm" => "example", "require" => "valid-user") )
alias.url = ( "" => "/usr/lib/git-core/git-http-backend" )
setenv.set-environment = ( "GIT_PROJECT_ROOT" => "/var/www/git/" )
setenv.set-environment += ( "GIT_HTTP_EXPORT_ALL" => "" )
cgi.assign = ( "" => "" )
}
步骤 6:仅允许安全的 HTTPS 连接¶
这很简单。只需为您的子域正常配置 HTTPS 即可。然后,将代码包装在 $HTTP["scheme"] == "http"
条件中,并使用 mod_redirect 将 HTTP 请求重定向到 HTTPS,从而创建最终配置
# git server over HTTPS configuration for lighttpd
# author: trevcan
# github.com/trevcan/
server.modules += ("mod_openssl")
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.privkey = "/etc/keys/yourdomain.com/privkey.pem"
ssl.pemfile = "/etc/keys/yourdomain.com/fullchain.pem"
}
# log CGI stderr to separate log
server.breakagelog = "/var/log/lighttpd/breakage.log"
# using mod auth with plain text module mod_authhn_file
server.modules += ("mod_auth", "mod_authn_file")
server.modules += ("mod_redirect", "mod_setenv", "mod_cgi", "mod_alias")
$HTTP["host"] == "git-test.yourdomain.com" {
ssl.privkey = "/etc/keys/git-test.yourdomain.com/privkey.pem"
ssl.pemfile = "/etc/keys/git-test.yourdomain.com/fullchain.pem"
$HTTP["scheme"] == "http" {
url.redirect = ("" => "https://${url.authority}${url.path}${qsa}")
#url.redirect-code = 308 # (before lighttpd 1.4.75)
} else {
# password file is at /home/www-data/user-info
# example plain-text password file:
# agent007:secret
auth.backend = "plain"
auth.backend.plain.userfile = "/home/www-data/user-info"
# this must be set to require auth under this domain.
auth.require = ( "" => ("method" => "basic", "realm" => "example", "require" => "valid-user") )
}
alias.url = ( "" => "/usr/lib/git-core/git-http-backend" )
setenv.set-environment = ( "GIT_PROJECT_ROOT" => "/var/www/git/" )
setenv.set-environment += ( "GIT_HTTP_EXPORT_ALL" => "" )
cgi.assign = ( "" => "" )
}
参考¶
- Smart HTTP Git 文档。
- Lighttpd 文档 Mod Auth
- Lighttpd 文档 Mod CGI
- Lighttpd 文档 Mod SetEnv
- Lighttpd 文档 Mod Alias
- Lighttpd 文档 Mod Redirect
- Lighttpd 文档 TLS/SSL