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:
- Confirm you have Apache 2.2 installed: rpm -q httpd (install it with yum otherwise)
- 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
- Update your httpd.conf to include this:
SetEnv GIT_PROJECT_ROOT /var/www/html/git SetEnv GIT_HTTP_EXPORT_ALL ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
- Add LDAP Authentication (in this case, any valid LDAP user will have access to the git location) as follows:
<LocationMatch "^/git/.*/git-receive-pack$"> SSLRequireSSL Order deny,allow Deny from All AuthName "GIT Repo" AuthType Basic AuthBasicProvider ldap AuthzLDAPAuthoritative off AuthLDAPURL "ldap://ldap-server.company.com:389/ou=users,o=company?uid" Require valid-user </LocationMatch>
- 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*"> SSLRequireSSL 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://ldap-server.company.com:636/ou=users,o=company?uid" AuthLDAPGroupAttribute member AuthLDAPGroupAttributeIsDN on Require ldap-group cn=my.group,ou=groups,o=company Satisfy any </LocationMatch>
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 “my.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 https://mygitserver.company.com/git/project.git 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.