[2010 年 9 月 16 日更新]
昨晚研究完这个问题后,我意识到我最初的问题实际上是在问两个不同的事情:
1) 是否可以为 gitosis 创建的所有远程存储库设置更新后挂钩(即在 gitosis 中创建存储库后不必手动执行)。这对于通过 HTTP 进行克隆是必要的(哑 HTTP 客户端依赖于从更新后挂钩中调用的mv hooks/post-update.sample hooks/post-update
事实)。git update-server-info
2)一旦可以通过 HTTP 访问存储库,是否可以使用 gitosis.conf 中的选项(类似于daemon = no
或gitweb = yes
)打开或关闭访问
--- 问题 1 的解答 ---
事实证明,Git 使用模板通过命令创建新的存储库git init
。通过mv hooks/post-update.sample hooks/post-update
在模板目录中执行,git init
我服务器上的所有未来调用都将正确配置更新后挂钩。(在 OSX 上,模板目录适用/opt/local/share/git-core/templates/
于那些关心的人)
要实现此功能,另一个要求是打开 Apache 重写规则,以便存储库的 HTTP 克隆 URL 如下所示http//git.example.com/repo.git
我的重写规则/etc/apache2/extra/httpd-vhosts.conf
如下所示:
# turning on mod rewrite
RewriteEngine on
# make the front page an internal rewrite to the gitweb script
RewriteRule ^/$ /cgi-bin/gitweb.cgi [L,PT]
# make access for "dumb clients" work
RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ /cgi-bin/gitweb.cgi%{REQUEST_URI} [L,PT]
--- 仍在寻找问题 2 的解决方案...帮忙!:) ---
现在 HTTP 克隆适用于我的所有存储库,我想知道是否有办法使用 gitosis 来管理 HTTP 访问控制。设置daemon = no
并gitweb = no
关闭存储库的 git-daemon 和 gitweb 访问,但由于 Apache 重写规则仍然打开,仓库仍然可以克隆在http://git.example.com/repo.git
。关于如何使用 gitosis 来管理这个问题,有什么想法吗?
[我最初发布的问题]
是否可以使用 gitosis 管理对 git 存储库的 http 访问?例如,在 gitosis.conf 中,我可以使用以下命令管理 gitweb 和 git-demon 的访问:
# Allow gitweb to show this repository.
gitweb = yes
# Allow git-daemon to publish this repository.
daemon = no
我目前可以通过发出以下命令来克隆我的存储库:
$ git clone git://git.example.com/repo.git
但是,当我发出以下命令时:
$ git clone http://git.example.com/repo.git
我收到以下错误消息:
fatal: http://git.example.com/repo.git/info/refs not found: did you run git update-server-info on the server?
但是,如果我登录到我的服务器并从 repo.git 中运行以下命令:
# From http://progit.org/book/ch4-5.html
$ cd project.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update
$ git update-server-info
然后通过 http 克隆就可以正常工作。
有没有办法从 gitosis 内部管理对存储库的 http 访问?
答案1
Gitosis 使用 gitweb 来通过 http 发布仓库。
您需要运行 gitweb。
请确保已安装 gitweb。您的 gitweb.conf 应如下所示:
# Location of the git binary
$GIT = "/usr/bin/git";
# Project root for gitweb
$projectroot = "/srv/git/repositories";
$stylesheet = "/gitweb.css";
$logo = "/git-logo.png";
$favicon = "/git-favicon.png";
# Site name
$site_name = "My site";
# URL formatting
#$my_uri = "http://git.somewhere.net/";
#$home_link = $my_uri;
# Base URL for project trees
@git_base_url_list = ("ssh://git\@somewhere.net");
# Length of the project description column in the webpage.
$projects_list_description_width = 50;
# Which repos are allowed to export
$export_ok = "git-daemon-export-ok";
# Enable PATH_INFO so the server can produce URLs of the
# form: http://git.hokietux.net/project.git/xxx/xxx
$feature{'pathinfo'}{'default'} = [1];
# Enable blame, pickaxe search, snapshop, search, and grep
$feature{'blame'}{'default'} = [1];
$feature{'blame'}{'override'} = [1];
$feature{'pickaxe'}{'default'} = [1];
$feature{'pickaxe'}{'override'} = [1];
$feature{'snapshot'}{'default'} = [1];
$feature{'snapshot'}{'override'} = [1];
$feature{'search'}{'default'} = [1];
$feature{'grep'}{'default'} = [1];
$feature{'grep'}{'override'} = [1];
apache 中的 gitweb 配置示例:
Alias /gitweb/gitweb.css /usr/share/gitweb/gitweb.css
Alias /gitweb/git-logo.png /usr/share/gitweb/git-logo.png
Alias /gitweb/git-favicon.png /usr/share/gitweb/git-favicon.png
ScriptAlias /gitweb /usr/lib/cgi-bin/gitweb.cgi
<Directory /usr/share/gitweb>
Options FollowSymLinks +ExecCGI
AddHandler cgi-script .cgi
</Directory>
<Location /gitweb>
Order allow,deny
Allow from all
#AuthType Basic
#AuthName "GITOLITE"
#AuthUserFile /etc/apache2/gitweb.htpasswd
#Require valid-user
</Location>
# Securing with users example
<Location /gitweb/SomethingToHide.git>
Require user myusername
</Location>
我已改用 gitolite 因为......
- 更易于使用
- 它有更多选项(安全、分组等)
答案2
问题是您无法限制从 http:// 克隆的访问,因为 Apache 直接处理这些请求。我已经开发了一个使用 git hooks 和文件权限的解决方案。
我在共享托管环境中设置了 Redmine/Gitosis/Gitweb 服务器,其中 Apache 用户是不是gitosis 用户。默认情况下,Apache 无权访问我的存储库,因为 gitosis 使用 750 权限创建它们。我已让 gitosis 成功填充其用于 gitweb 的 projects.list,位于 /home/xdgit/gitosis/projects.list,其中包含应被视为可公开访问的所有存储库的名称。我已修改了我的 gitosis-admin.git/hooks/post-update 钩子以包含以下内容:
#!/bin/sh
set -e
gitosis-run-hook post-update
git-update-server-info
# Find repo root from ENV or current dir
GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
if [ -z "$GIT_DIR" ]; then
echo >&2 "fatal: post-receive: GIT_DIR not set"
exit 1
fi
# Process permissions for each repo
for f in $GIT_DIR/../*.git
do
# Look for the repo name in projects.list
if grep -q `basename $f` /home/xdgit/gitosis/projects.list
then chmod o+rx $f
else chmod o-rx $f
fi
done
现在,每当我将任何内容推送到 gitosis-admin.git(例如更改 gitosis.conf 以允许存储库的公共访问)时,更新后挂钩都会自动更改存储库的权限以允许或拒绝公共访问,具体取决于存储库的名称是否出现在 projects.list 中。由于虚拟客户端要求实际的存储库可由 Apache 直接访问,这种基于权限的访问控制是理想的解决方案 —— 即使 Apache 也无法访问非公开的存储库。
我还开发了一个 mod_rewrite/mod_setenvif 解决方案,用于检测存储库中是否存在 git-daemon-export-ok 文件,并在适当的情况下允许访问。它确实有效,但需要采取额外的预防措施来明确禁止访问如果 Apache 可以读取非公开存储库(必须可以读取),则将其复制到非公开存储库。这真是令人头痛不已,而且就我而言(因为无论如何都必须更改文件权限),这实在是太过分了。希望这能有所帮助。