Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I enable anonymous read access (pull) but authenticated write access (push) to a git repository over http?

I want to have git repository available via "smart" HTTP to which only I can push, but which anybody (or anybody with account) can clone / fetch from.

In the git-http-backend(1) manpage one can find the following example configuration for Apache web server:

Ensure mod_cgi, mod_alias, and mod_env are enabled, set GIT_PROJECT_ROOT (or DocumentRoot) appropriately, and create a ScriptAlias to the CGI:

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

To enable anonymous read access but authenticated write access, require authorization with a LocationMatch directive:

<LocationMatch "^/git/.*/git-receive-pack$">
        AuthType Basic
        AuthName "Git Access"
        Require group committers
        #...
</LocationMatch>

Unfortunately this configuration doesn't work. I can fetch / clone repository without any problems, without requiring authenthication, but pushing fails:

$ git push origin master
error: Cannot access URL http://localhost/git/test.git/, return code 22
fatal: git-http-push failed

Examining error.log of Apache web server doesn't help:

[...] Service not enabled: 'receive-pack'
[...] Request not supported: '/var/www/git/test.git/'

The access.log tells us that git push first uses GET method on /git/test.git/info/refs?service=git-receive-pack query-based URL, which is not covered by LocationMatch directive:

[...] "GET /git/test.git/info/refs?service=git-receive-pack HTTP/1.1" 403 304 "-" "git/1.7.10.4"
[...] "GET /git/test.git/info/refs HTTP/1.1" 200 267 "-" "git/1.7.10.4"
[...] "GET /git/test.git/HEAD HTTP/1.1" 200 337 "-" "git/1.7.10.4"
[...] "PROPFIND /git/test.git/ HTTP/1.1" 404 250 "-" "git/1.7.10.4"

(the following lines are about fallback to "dumb" WebDAV based HTTP push - is it possible to disable this fallback?).


For now I use the following workaround: I require valid user for both fetch and push (using modified configuration from "authentication for both reads and writes" example in git-http-backend(1) manpage), and restrict push to single user via pre-receive hook by examining REMOTE_USER environment variable.

like image 515
Jakub Narębski Avatar asked Dec 09 '12 22:12

Jakub Narębski


People also ask

Which of the following protocol can be used to access remote repository in Git?

SSH URLs provide access to a Git repository via SSH, a secure protocol. To use these URLs, you must generate an SSH keypair on your computer and add the public key to your account on GitHub.com.

Is Git over HTTP?

Git can communicate over HTTP using two different modes. Prior to Git 1.6. 6, there was only one way it could do this which was very simple and generally read-only. In version 1.6.

What is Git HTTP backend?

A simple CGI program to serve the contents of a Git repository to Git clients accessing the repository over http:// and https:// protocols. The program supports clients fetching using both the smart HTTP protocol and the backwards-compatible dumb HTTP protocol, as well as clients pushing using the smart HTTP protocol.


2 Answers

One not so complex alternative is to use gitolite in addition of your Apache-git setup.
You can plug gitolite to Apache easily enough (no ssh config required).

See as an example: httpd.conf, combined with this local gitolite installation script.

You can then easily declare Apache logins for Write access, and @all for read access.

like image 137
VonC Avatar answered Nov 15 '22 06:11

VonC


You have to update your repo .git/config file with the following value:

[http]
    receivepack = true
like image 24
arch Avatar answered Nov 15 '22 08:11

arch