Назад | Перейти на главную страницу

Управление http-доступом к репозиториям git с помощью gitosis

[Обновление от 16.09.2010]

Изучив это прошлой ночью, я понял, что в моем первоначальном вопросе действительно были две разные вещи:

1) Можно ли установить ловушку после обновления для всех удаленных репозиториев, созданных gitosis (т.е. не нужно вручную выполнять mv hooks/post-update.sample hooks/post-update ибо после создания репозитория в гитозисе). Это необходимо для работы клонирования через HTTP (глупые HTTP-клиенты полагаются на то, что git update-server-info вызывается из обработчика post-update).

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, чтобы URL-адрес клона HTTP для репозитория выглядел как 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 работает для всех моих репозиториев, мне интересно, есть ли способ управлять контролем доступа HTTP с помощью gitosis. Настройка daemon = no и gitweb = no отключает доступ git-daemon и gitweb к репозиторию, но, поскольку правила перезаписи Apache все еще действуют, репо все еще можно клонировать в http://git.example.com/repo.git. Есть идеи, как использовать gitosis, чтобы справиться с этим?

[Вопрос, который я изначально разместил]

Можно ли управлять HTTP-доступом к репозиториям git с помощью gitosis? Например, в 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 работает нормально.

Есть ли способ управлять http-доступом к репозиторию из gitosis?

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];

Пример конфигурации gitweb в apache:

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>

Я перешел на гитолит, потому что ...

  • легче использовать
  • у него больше возможностей (безопасность, группировка и т. д.)

Проблема в том, что вы не можете ограничить доступ к клонированию с http: //, потому что Apache обрабатывает эти запросы напрямую. Я разработал решение, используя git-хуки и права доступа к файлам.

У меня есть сервер Redmine / Gitosis / Gitweb, настроенный в среде общего хостинга, в которой пользователь Apache не пользователь гитозиса. По умолчанию Apache не имеет доступа к моим репозиториям, потому что gitosis создает их с 750 разрешениями. У меня есть gitosis, успешно заполняющий свой projects.list для gitweb в /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 (что должно быть). Это оказалось огромной головной болью, и в моем случае (поскольку права доступа к файлам все равно пришлось бы изменить) это было крайним излишеством. Надеюсь это поможет.