2012年7月11日 星期三

一步步架設 GIT server(2) --- GIT remote with HTTP-dav server

透過 SSH 有先天上的存取權限問題, 解法也很直觀
1. 透過 SSH public key cipher
2. 改用 HTTP/HTTPS server

今天就讓我們試試看 GIT HTTP 的架設
Server : my.web.server
Path : /var/git/project.git
WebPage : /project.git


First, we have to describe some concept :
A GIT HTTP server is a git server, using webdav file system through http protocol.

The result structure looks like

Server Side

1. HTTPD(auth and server control)
2. WebDav(access method and exceptions)
3. File System(www-data read/write permission for contain files)
4. GIT bare server(GIT protocol)

For this 4 rules, we will set them to

1. HTTPD(auth and server control) -- setting up basic authtype and password file

2. WebDav(access method and exceptions) -- setting no access limit to read and directory listing, auth limitation for write and create

3. File System(www-data read/write permission for contain files) -- be sure all file under the repositories with www-data as owner and group
4. GIT bare server(GIT protocol) -- create a bare server by git init -- bare


My first try follows the guide in this page , using the following git_project1.conf :

Alias /project1.git /var/www/project1.git


Allow from all



    DAV on
    AuthType Basic
    AuthName "Git"
    AuthUserFile /etc/apache2/passwd.git
    Require valid-user
After restarting apache2 server, issuing git clone command "git clone http://Git@localhost/project1.git", we got an error
Cloning into 'project1'...
Password for 'http://Git@localhost':
error: The requested URL returned error: 401 (curl_result = 22, http_code = 401, sha1 = 515a49392b55fead641c664d771776b0580e2ac2)
error: Unable to find 515a49392b55fead641c664d771776b0580e2ac2 under http://Git@localhost/project1.git
Cannot obtain needed blob 515a49392b55fead641c664d771776b0580e2ac2
while processing commit ecc69bb265fbcb017e472fa0f12d7260ff106f29.
error: Fetch failed.
After searching the solutions, we guess this is a apache-dav-git cowork bug : all file accessing requires authentication but only first file gets a user/password prompt.



Second, we tried a git-http-backend suggestion.

Here is the setting of git_project2.conf

Alias /project2.git /var/www/project2.git


Allow from all



DAV on
AuthType Basic
AuthName "Git"
AuthUserFile /etc/apache2/passwd.git
Require valid-user

This worked for git clone "git clone http://Git@localhost/project2.git" but failed on push and got the following message :

#> git push origin master
Password for 'http://Git@localhost':
error: Cannot access URL http://Git@localhost/project2.git/, return code 22
fatal: git-http-push failed

Due to error 22 is confusing, we got block here for a long day. Finally we know that this error means the file accessing in project2 requires authentication but we didn't set. The reason is got no match.

And additionally, if we change the project2 setting to project1, the push could work, where we have to type password twice.




It is time to review the behavior of webdav. The 1 and 2 lead to a simple conclusion : we only have to make read/list require no auth and write/change/create require auth.

Here is the final try

Alias /project3.git /var/www/project3.git


Allow from all



    DAV on
    AuthType Basic
    AuthName "Git"
    AuthUserFile /etc/apache2/passwd.git
   
        require valid-user
   


Finally it works for both clone/fetch and push.




Here is another option : git-http-backend
It uses a "backend" ( in /usr/lib/git-core/git-http-backend ).
It works in a cgi-behavior fasion.
First, we create a "backend_git.conf" under "mods-available" and link to "mods-enabled"

Content of backend_git.conf
#
#  Basic setup for git-http-backend
#

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


        AuthType Basic
        AuthName "Git"
        Require valid-user
        AuthUserFile /etc/apache2/passwd.git

Then we put our git server in /var/www/git, then it works.
There are some possibilities :
1. To read for all and push with authentication

        AuthType Basic
        AuthName "Git"
        Require valid-user
        AuthUserFile /etc/apache2/passwd.git
2. To serve multiple git repositories
SetEnvIf Request_URI "^/git/([^/]*)" GIT_NAMESPACE=$1
ScriptAliasMatch ^/git/[^/]*(.*) /usr/libexec/git-core/git-http-backend/storage.git$1
3. To serve gitweb for some file and git repositories for others
ScriptAliasMatch \
        "(?x)^/git/(.*/(HEAD | \
                        info/refs | \
                        objects/(info/[^/]+ | \
                                 [0-9a-f]{2}/[0-9a-f]{38} | \
                                 pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
                        git-(upload|receive)-pack))$" \
        /usr/libexec/git-core/git-http-backend/$1

ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/
 


沒有留言: