0

My goal is to get anonymous read access (git clone / git pull) and authentified write access (git push) to a git bare repository via HTTP/HTTPS over an Apache2 web-server 2.4.29.

I try out the documented configuration (https://git-scm.com/docs/git-http-backend):

SetEnv GIT_PROJECT_ROOT /var/www/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/

... in both variants ...

Variant 1) With module mod_rewrite:

RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
RewriteCond %{REQUEST_URI} /git-receive-pack$
RewriteRule ^/git/ - [E=AUTHREQUIRED:yes]

<LocationMatch "^/git/">
    Order Deny,Allow
    Deny from env=AUTHREQUIRED
    AuthType Basic
    AuthName "Git Access"
    AuthBasicProvider ldap
    AuthLDAPURL ldap://ldapserver:386
    Require user test
    Satisfy Any
</LocationMatch>

Variant 2: Without module mod_rewrite:

<LocationMatch "^/git/.*/git-receive-pack$">
    AuthType Basic
    AuthName "Git Access"
    AuthBasicProvider ldap
    AuthLDAPURL ldap://ldapserver:386
    Require user test
</LocationMatch>

<LocationMatch "^/git/">
    Require all granted
    Allow from all
</LocationMatch>

I am using debian package apache2 (2.4.29-1ubuntu4.14) on server side and git 2.29.2 on client side to test the configuration.

Both variants are not working.

Manfred Steiner
  • 1,215
  • 2
  • 13
  • 27

1 Answers1

0

The problem is caused by uncomplete documentation https://git-scm.com/docs/git-http-backend.

For Variant 1 (with module mod_rewrite) it is needed to enable the rewrite engine. Adding RewriteEngine On solves the problem. With the proper LogLevel statement (commented out in the following example), you can observe the proper behavior in apache2 log file.

RewriteEngine On
#LogLevel alert rewrite:trace6

SetEnv GIT_PROJECT_ROOT /var/www/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/

For Variant 2 (without module rewrite_mod) the LocationMatch will not match in my case, because a git pull is done with a query string:

GET /git/repo.git/info/refs?service=git-receive-pack

The described LocationMatch is not able to check the query string of the request.
See http://httpd.apache.org/docs/2.0/en/mod/core.html#location ...

No scheme, hostname, port, or query string may be included.

A solution is to add <If>...</If><Else>...</Else> inside LocationMatch (see also 2019594). With the CustomLog statement it is possible to check in log file if LocationMatch is working as desired (see https://serverfault.com/questions/718234/how-to-check-if-locationmatch-regex-is-working).

CustomLog ${APACHE_LOG_DIR}/location.log "%h %l %u %t \"%r\" %>s %b what:%{INDICATOR_VAR}e"

<LocationMatch "^/git/">
    <If "%{QUERY_STRING} =~ /service=git-receive-pack/">
         SetEnv INDICATOR_VAR "git push"
         AuthType Basic
         AuthName "Git Access"
         AuthBasicProvider ldap
         AuthLDAPURL ldap://ldapserver:386
         Require user test
         Allow from all
    </If>
    <Else>
         SetEnv INDICATOR_VAR "git pull"
         Require all granted
         Allow from all
    </Else>
</LocationMatch>

Manfred Steiner
  • 1,215
  • 2
  • 13
  • 27