Centos + cPanel + git (specifically git-http-backend) integration

Bethybooth

Member
Nov 5, 2008
5
0
51
Good morning everyone,

One of my servers is set up as follows:

  • CENTOS 6.6 x86_64 standard
  • WHM 11.46.2 (build 4)
  • Apache 2.4 (including mod_env)
  • PHP 5.5

I want to use the machine not only as a web /email server, but also as a git repository for our development work, with access provided over HTTPS rather than SSH, as it's currently underutilised (though feel free to argue that I should set up users for SSH connections instead).

(I've anonymised the username, that is the primary intended host, to be "userhere")

To that end, using:

Software » Install an RPM

I've installed git (all, version 2.2.0).

Through SSH I've added a symbolic links to make git and git-http-backend available to the users:

Code:
ln -s /usr/local/cpanel/3rdparty/bin/git /usr/local/bin/git
ln -s /usr/local/cpanel/3rdparty/libexec/git-core /usr/local/libexec/git-core
I've (among others) got a test bare git repository:

Code:
cd /home/userhere/securearea/gitrepositories
mkdir testgitrepo
cd testgitrepo
git --bare init
I've set up:

Service Configuration » Apache Configuration » Include Editor
Post VirtualHost Include

as:
Code:
SetEnv GIT_PROJECT_ROOT /home/userhere/securearea/gitrepositories
SetEnv GIT_HTTP_EXPORT_ALL

SetEnv REMOTE_USER $REDIRECT_REMOTE_USER

<Directory /usr/local/libexec/git-core>
   Options ExecCGI Indexes
   Order allow,deny
   Allow from all
</Directory>

ScriptAliasMatch "^/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/local/libexec/git-core/git-http-backend/$1
ScriptAlias /git/ /home/userhere/public_html/cgi-bin/gitweb.cgi/


<Directory "/home/userhere/securearea/gitrepositories">
   Options Indexes
   Order allow,deny
   Allow from all
</Directory>

(You can see some rather desperate additions of indexes where I'm trying to work out just where the problem is)

I've copied gitweb.cgi from its home to the aforementioned directory, and set it up with the correct variables, eg: our $projectroot = "/home/userhere/securearea/gitrepositories";

The cgi access to gitweb.cgi works just fine, but I simply cannot clone the repositories I have hosted. From my local machine I've tried:

Code:
git clone https://myserver/git/testgitrepo/
Which reports a 500 server error, where the Apache error logs show the following:

"GET /git/testgitrepo/info/refs?service=git-upload-pack HTTP/1.1" 404 - "-" "git/1.9.5.msysgit.0"

So 404 or 500? Well to be fair /testgitrepo/info/refs doesn't exist, but then ScriptAliasMatch should be turning that into:

/usr/local/libexec/git-core/git-http-backend/testgitrepo/info/refs?service=git-upload-pack

For reference, I have made sure that this isn't being caused by conflicting ScriptAlias and ScriptAliasMatch, by changing the ScriptAlias to work (again successfully) under a different directory match. I've also tried a straight ScriptAlias /git/ /usr/local/libexec/git-core/git-http-backend/ to remove the RegEx from the equation.


Please could anyone advise me where I might be going wrong?

Once this is set up, there's still the security to add, which I'm sure will be a breeze once this is working!

B
 

Bethybooth

Member
Nov 5, 2008
5
0
51
It's worth adding that I can clone directories over SSH:

Code:
git clone ssh://[email protected]:mysshport/home/userhere/securearea/gitrepositories/testgitrepo/
or even:
Code:
git clone ssh://[email protected]:mysshport/~/securearea/gitrepositories/testgitrepo/
This is all fine and happy, but my intention was to keep the ability to read, and write to, these repositories controlled by usernames and passwords purely for this service, and limit access accordingly in that way (I don't want to be giving shell access to this server to all the software developers)

So really it is just a question of how I set up git-http-backend with the cPanel managed Apache configuration.

I'm wondering if this is going to be something like putting the Environment Variables, Script Aliases and Directory security into the Virtual Hosts configuration and distilling the config to hold any changes upon upgrades.

Any help, very gratefully received,

B
 

cPanelMichael

Administrator
Staff member
Apr 11, 2011
47,880
2,260
463
The cgi access to gitweb.cgi works just fine, but I simply cannot clone the repositories I have hosted. From my local machine I've tried:

git clone https://myserver/git/testgitrepo/

Which reports a 500 server error, where the Apache error logs show the following:

"GET /git/testgitrepo/info/refs?service=git-upload-pack HTTP/1.1" 404 - "-" "git/1.9.5.msysgit.0"

So 404 or 500? Well to be fair /testgitrepo/info/refs doesn't exist, but then ScriptAliasMatch should be turning that into:
Hello :)

Do you notice any additional entries in /usr/local/apache/logs/error_log when this happens?

Thank you.
 

Bethybooth

Member
Nov 5, 2008
5
0
51
Thanks Michael, you're spot on - it looks like a permissions error for Apache suEXEC:

/usr/local/apache/logs/error_log:
Code:
[cgi:error] [pid 18911] [client [I]My IP[/I]:60317] AH01215: suexec policy violation: see suexec log for more details
[cgi:error] [pid 18911] [client [I]My IP[/I]:60317] End of script output before headers: git-http-backend
/usr/local/apache/logs/suexec_log:
Code:
uid: (502/userhere) gid: (513/userhere) cmd: git-http-backend
error: target uid/gid (502/513) mismatch with directory (0/0) or program (0/0) or trusted user (0/10)
So I copied the git-core directory into /home/userhere and set the ownership of the local version (Is there a better option I should consider?):

Code:
cp -R /usr/local/cpanel/3rdparty/libexec/git-core /home/[I]userhere[/I]
cd /home/[I]userhere[/I]/gitcore
chown -R [I]userhere[/I]:[I]userhere[/I] git-core
Adjusted the Post VirtualHost Include accordingly (not copied; just roughly what I have in place now):
Code:
SetEnv GIT_PROJECT_ROOT /home/userhere/public_html/gitrepositories
SetEnv GIT_HTTP_EXPORT_ALL

<Directory /home/userhere/git-core>
   Options ExecCGI Indexes
   Order allow,deny
   Allow from all
</Directory>

ScriptAliasMatch "^/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))$" /home/userhere/git-core/git-http-backend/$1

<Directory "/home/userhere/public_html/gitrepositories">
   Options Indexes
   Order allow,deny
   Allow from all
</Directory>
Obviously this should be done on a per user basis (ie: Modifying the vhosts.conf), but this particular machine only has two users, so it's good enough for now.

Important notes:

At this point, I had an easy fix with some permissions. Despite setting GIT_HTTP_EXPORT_ALL, I still had to add the git-daemon-export-ok empty file to each .git directory. From the perspective of this particular install, it would be nice to have the environment variable being recognised (the boss will at some point make a new repository, not follow any instructions I give about adding the file and then complain that it's broken!)

More importantly though; I initially left the repository located in the /home/userhere/securearea/gitrepositories folder, but it became obvious that the GIT_PROJECT_ROOT variable was also being ignored, and the root was being treated as /home/userhere/public_html (hence the changes to having the repository in the sub-directory of public_html)

Checking whether the SetEnv GIT_PROJECT_ROOT was actually having any impact, when logged in to the shell as either the user or as root, echo $GIT_PROJECT_ROOT is blank.

As a result, this works:
Code:
git clone https://myserver/git/gitrepositories/testgitrepo
Where the aim is obviously:
Code:
git clone https://myserver/git/testgitrepo
So the questions now: Would SetEnv cause an error in the Post VirtualHost Include modifications if it wasn't installed? (phpinfo() isn't showing mod_env, so it looks like I'll be doing an easyApache rebuild overnight tonight)

(Hopefully once this is set up, we can put a guide in the Workarounds and Optimization forum)

B
 

cPanelMichael

Administrator
Staff member
Apr 11, 2011
47,880
2,260
463
Thank you for taking the time to explain the changes you made. That should help other users who visit this thread in the future.

So the questions now: Would SetEnv cause an error in the Post VirtualHost Include modifications if it wasn't installed? (phpinfo() isn't showing mod_env, so it looks like I'll be doing an easyApache rebuild overnight tonight)
I believe that Apache module is installed by default. You can verify that with a command such as:

Code:
httpd -M|grep env
You can run "/scripts/rebuildhttpdconf" to verify if the Apache configuration file and includes are syntactically correct.

Thank you.
 

Bethybooth

Member
Nov 5, 2008
5
0
51
Thanks Michael, I really appreciate your time on this.

Indeed, env_module is installed (and it is default in the easyApache setup)

Syntax of the configuration is correct, and having looked at the phpinfo() more carefully, those environment variables are present for PHP if not git-http-backend.

I did the easyApache build anyway, because I'd prepared myself for the scenario of having to test all the active services that are running. All went very smoothly, I'm pleased to report, but sadly still no change on the environment variables front.

As this has left me with the repositories in a hosted folder (under public_html) I've taken the precaution of adding an .htaccess file which stops any access from prying eyes (in the gitrepositories sub directory) and redirects to appear as any other 404 on the site:

Code:
Order Deny,Allow
Deny from All

ErrorDocument 403 /404.php
For security on the repository, I've opted to make life a little easier: I've added a folder called "wip" and used the nice cPanel interface to add users and passwords, then referenced those passwords for access via Git. In the "wip" folder I'm trying out GitList, which is a much nicer looking interface than gitweb.cgi.

So my Post VirtualHost Include currently looks like this:

Code:
SetEnv GIT_PROJECT_ROOT /home/[I]userhere[/I]/public_html/gitrepositories
SetEnv GIT_HTTP_EXPORT_ALL
SetEnv REMOTE_USER $REDIRECT_REMOTE_USER

<Directory /home/[I]userhere[/I]/git-core>
   Options ExecCGI Indexes
   Order allow,deny
   Allow from all
</Directory>

ScriptAliasMatch "^/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))$" /home/[I]userhere[/I]/git-core/git-http-backend/$1

<Location "/git/">
  AuthType Basic
  AuthName "Git Repositories"
  AuthUserFile "/home/[I]userhere[/I]/.htpasswds/public_html/wip/passwd"
  require valid-user
</Location>
So the top three lines are doing nothing, which is unfortunate, but I now have password protected repositories, so I'm most of the way there in terms of the end goal.

I'd still be very interested in getting the environment variables working, especially GIT_HTTP_EXPORT_ALL,

B
 

Bethybooth

Member
Nov 5, 2008
5
0
51
Hi Armin,

I didn't get any further than my last post, but I am going to spend some time on this again next week.

Are you in similar position? Do you have the Environment variables working as you'd expect?

B