简体   繁体   中英

Setting up private multiple public/private Git repositories with Apache and mod_macro

I have always been running SVN repositories on my private server. I had a few projects to maintain, all are maintained using a standard configuration pattern that came to be used as an Apache macro . Basically my structure is pretty straightforward

Mapped on

  • /home/me/srv/svn/repos
    • /repo1
    • /repo2

There are multiple macros, because each repository has its own authentication scheme (public read, authenticated commit or completely private)

Now I want to go to Git

Even if I have found a few configuration directives for using Apache and Git, I haven't understood them correctly. Following is my question:


I want my virtual host ( https://git.example.com ) to host multiple Git repositories, all configurable with ease from shell (eg adding a mod_macro 's Use directive and running git init via SSH). Each one having its own permission system, eg according to .htpasswd . A typical repository path can be https://git.example.com/[projects-or-whatever]/myProject.git mapped to somewhere like /home/me/srv/git/repos/myProject

How to do that in Apache?


So far so bad

I tried to build a Git configuration like the following (not yet tested as it won't do a thing for now)

<VirtualHost *:443>
    ServerName git.example.com
    ServerAlias www.git.example.com
    ServerAdmin me@example.com
    AssignUserID me myself

    # Use HTTP Strict Transport Security to force client to use secure connections only
    Header always set Strict-Transport-Security "max-age=500000000"

    ErrorLog /path/to/error_log
    CustomLog /path/to/access_log "vhost_combined"

    DocumentRoot /srv/www/default

    SSLEngine on
    SSLOptions +StrictRequire
    #SSLPassPhraseDialog builtin
    SSLCertificateFile /path/to.crt
    SSLCertificateKeyFile /path/to.key
    SSLCertificateChainFile /path/to.ca-bundle
    SSLVerifyClient none
    SSLProxyEngine on

    #Used for system login instead of .htaccess
    AddExternalAuth pwauth /usr/bin/pwauth
    SetExternalAuthMethod pwauth pipe

    <IfModule mime.c>
        AddType application/x-x509-ca-cert      .crt
        AddType application/x-pkcs7-crl         .crl
    </IfModule>



    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/lib/git/git-http-backend/$1"

    ScriptAlias /git /usr/share/gitweb/gitweb.cgi
    SetEnv GIT_PROJECT_ROOT /home/me/srv/git/repos/
    SetEnv GIT_HTTP_EXPORT_ALL


    #In this directory, specific repositories are configured
    Include "/home/hosting/vhosts.d/me/git/*.git.conf"

    <Directory "/home/me/srv/git/repos">
        Allow from all
        Options +ExecCGI
        AllowOverride All
    </Directory>


    <Directory "/usr/lib/git/">
        Options ExecCGI Indexes
        Order allow,deny
        Allow from all
    </Directory>

    AddHandler cgi-script cgi
    DirectoryIndex gitweb.cgi

    <Files gitweb.cgi>
        SetHandler cgi-script
    </Files>
</VirtualHost>

But let's focus on the following line that I can't understand right now

 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/lib/git/git-http-backend/$1"

From my understanding the above regex matches absolute paths like

/git/sdf/HEAD
/git/blablabla/blabla/objects/info/sdfs
/git/daf/git-receive-pack

Ok, looks like that all of my projects will be placed under /git/ if I don't change that, is that correct ?

But then, since I don't currently know how the Git over HTTP protocol works, how do I secure each repository independently from the others ?

Digging the book might provide the answer. Here is the candidate answer before I try it.

Basically the above global configuration tells that everything ending with the given pattern (eg git-receive-pack ) is sent to the Git CGI. OK.

But using proper LocationMatch , Alias and <Directory> directives should work. Here is a draft:

  • Use Alias to map a file system directory to a location
  • Use <Directory> to set up .htaccess if needed. SVN used HTTP verbs to distinguish read/write operation, Git uses git-receive-pack for writes. The book suggests using a LocationMatch directive
  • Wrap everything in a Macro

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM