Setting up GIT with Apache Smart HTTP/S and LDAP

I recently was put on a project to explore how we could use GIT over HTTP and integrate with our existing LDAP for authnz.  The reason for HTTP is that it is pretty easy to set-up and you can encrypt the content transfer with SSL.  Also, HTTP/S is firewall friendly.  The downside is that HTTP is a “dumb” protocol. The information here consolidates some information I found on the web to accomplish this.  I am using RHEL 6, Apache 2.2, OpenLDAP and msysgit for my GIT client on my Windows machine.

First off, HTTP wasn’t necessarily the fastest protocol to use with GIT until they added a mod called git-http-backend, or SMART-HTTP, as of GIT 1.6.6. This article from the Pro GIT author, @chacon, details this and from my experience I cut my download times by two-thirds using this approach.  Moreover, github is also supporting this.  Basically what you need to do is as follows:

  1. Confirm you have Apache 2.2 installed: rpm -q httpd (install it with yum otherwise)
  2. Clone your GIT repo to Apache by doing the following (as per Pro GIT book):
    $ cd /var/www/html/git (mkdir if necessary)
    $ git clone  --bare /path/to/git_project gitproject.git
    $ cd gitproject.git
    $ mv  hooks/post- update.sample  hooks/post- update
    $ chmod a+x  hooks/post- update 
  3. Update your httpd.conf to include this:
    SetEnv GIT_PROJECT_ROOT /var/www/html/git
    ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
  4. Add LDAP Authentication (in this case, any valid LDAP user will have access to the git location) as follows:
    <LocationMatch "^/git/.*/git-receive-pack$">
            Order deny,allow
            Deny from All
            AuthName "GIT Repo"
            AuthType Basic
            AuthBasicProvider ldap
            AuthzLDAPAuthoritative off
            AuthLDAPURL "ldap://,o=company?uid"
            Require valid-user
  5. Restart httpd: /etc/init.d/httpd restart

For LDAP authorization, of course you may have several different repos running off the same host, all which require certain users or groups access to the given location. This site explains this in detail, but here is an example I used so that I could bind a particular repo location to an LDAP group with SSL in place:

<LocationMatch "/git/gitproject*">
        Order deny,allow
        Deny from All
        AuthName "GIT Repo"
        AuthType Basic
        AuthBasicProvider ldap
        AuthzLDAPAuthoritative on
        LDAPTrustedGlobalCert CA_BASE64 /etc/pki/tls/http/rootCA.crt
        AuthLDAPURL "ldaps://,o=company?uid"
        AuthLDAPGroupAttribute member
        AuthLDAPGroupAttributeIsDN on
        Require ldap-group,ou=groups,o=company
        Satisfy any

In this example, I’m binding project.git (use wildcard for LocationMatch in-case users forget to add .git extension) to any member in the LDAP group “”. Note that you may need to define a different LDAP group attribute to match the field that will contain the DN of your users .  If you are not storing DN, then you can set AuthLDAPGroupAttributeIsDN to off.

The last step is enable SSL on your Apache server.  We use self-signed CERTs internally so you’re going to have to add those certs to your GIT clients unless of course your using a well known root CA like Verisign.  To do that with msysgit, you open the $MYSYSGIT_INSTALL/bin/curl-ca-bundle.crt and add the base-64 encoded text of your keys to the end of this file.  Then run the following command from the GIT BASH:

$ git config --global http.sslcainfo c:\\apps\\Git\\bin\\curl-ca-bundle.crt

That’s pretty much it!  Now you can simply connect to your repo from msysgit with SSL (no SSH keys req’d) and LDAP authorization:

$ git clone
Cloning Project...
Username: [put user name that's in the LDAP group]
Password: [password]
remote: Counting objects: 17, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 17 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (17/17), done.