I have git setup with my Apache2 server and it serves git request just fine. Now I want to setup Basic Authentication for this, so not everybody can use every directory. My goal is that only the ADMIN group has access to the complete /var/www/html/git
directory and my GITGROUP can access only /var/www/html/git/subdir
directories. However, while Apache is asking for credentials, with the setup (below) GITGROUP is still allowed to access all git directories. What am I doing wrong?
SetEnv GIT_PROJECT_ROOT /var/www/html/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/
<Directory /usr/lib/git-core>
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/apache2/.htpasswd"
AuthGroupFile "/etc/apache2/groups"
Require group ADMIN GITGROUP
Order allow,deny
Allow from all
</Directory>
<Directory /var/www/html/git>
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/apache2/.htpasswd"
AuthGroupFile "/etc/apache2/groups"
Require group ADMIN
Options -Indexes
Order allow,deny
Allow from all
</Directory>
<Directory /var/www/html/git/subdir>
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/apache2/.htpasswd"
AuthGroupFile "/etc/apache2/groups"
Require group ADMIN GITGROUP
Options -Indexes
Order allow,deny
Allow from all
</Directory>
EDIT:
Based on the answer by @jsvendsgaard I created two ScriptAlias lines for two symlinks to git-core. After that it is only a matter of assigning the correct GIT_PROJECT_ROOT:
ScriptAlias /gitdir1/ /var/www/html/gitdir1/git-core/git-http-backend/
ScriptAlias /gitdir2/ /var/www/html/gitdir2/git-core/git-http-backend/
<Directory "/var/www/html/gitdir1/git-core">
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/apache2/.htpasswd"
AuthGroupFile "/etc/apache2/groups"
Require group ADMIN
Options +ExecCGI -MultiViews -Indexes
Order allow,deny
Allow from all
</Directory>
<Directory "/var/www/html/gitdir2/git-core">
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/apache2/.htpasswd"
AuthGroupFile "/etc/apache2/groups"
Require group ADMIN GITGROUP
Options +ExecCGI -MultiViews -Indexes
Order allow,deny
Allow from all
</Directory>
<Location "/gitdir1/">
SetEnv GIT_PROJECT_ROOT /var/www/html/gitdir1
SetEnv GIT_HTTP_EXPORT_ALL
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/apache2/.htpasswd"
AuthGroupFile "/etc/apache2/groups"
Require group ADMIN
</Location>
<Location "/gitdir2/">
SetEnv GIT_PROJECT_ROOT /var/www/html/gitdir2
SetEnv GIT_HTTP_EXPORT_ALL
AuthType Basic
AuthName "Authentication Required"
AuthUserFile "/etc/apache2/.htpasswd"
AuthGroupFile "/etc/apache2/groups"
Require group ADMIN GITGROUP
</Location>
I believe I had a similar need. I was able to get my solution working on a RedHat server.
Solution Using Apache 2.4
The problem I found is that the git-http-backend script really controls all access to the repositories. Additionally, ScriptAlias is configured as such that it will be routing all /git/ requests to git-http-backend, regardless of the rest of the path. And, because you have provided access to this script for GITGROUP, that group will have access to any repository starting with /git/ in the URL. As per the documentation,
https://git-scm.com/docs/git-http-backend
git-http-backend knows the location to each repository because Apache is providing it with an environment variable. I suspect this means that git-http-backend is the only process on the server that directly accesses your repositories, and then provides the response back to Apache.
My solution adds a few extra steps. Essentially, you would force any access to git-http-backend to occur only after you have already authenticated to the location of your repository, not before. This is done by placing a link to the script in the repository directory itself, and then authenticating that location.
NOTE: I've only done this with bare repositories (git init --bare). I suspect that if for some reason you need to use a non-bare repository, this solution would need some tweaking (Ideas on that at the end):
In a nutshell:
Details:
ln -s /usr/libexec/git-core /var/www/html/git/subdir/git-core
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))$" \
"/var/www/html/git/$1/git-core/git-http-backend/$2"
<Location /git/subdir1.git> SetEnv GIT_PROJECT_ROOT /var/www/html/git/subdir1.git SetEnv GIT_HTTP_EXPORT_ALL AuthType Basic AuthName "Authorization Required" ... <the rest of your authentication details here> ... </Location> <Location /git/subdir2.git> SetEnv GIT_PROJECT_ROOT /var/www/html/git/subdir2.git SetEnv GIT_HTTP_EXPORT_ALL AuthType Basic AuthName "Authorization Required" ... <the rest of your authentication details here> ... </Location>
<Directory /var/www/html/git/subdir1.git/git-core> Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch -Indexes Allowoverride None </Directory> <Directory /var/www/html/git/subdir2.git/git-core> Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch -Indexes Allowoverride None </Directory>
If you're not using a bare repository:
I only use bare repositories on the git server, but I think that you might see an issue creating this symlink if you didn't have bare repositories. What I'm worried is that someone could somehow add your link to the repository. I'm not sure if this is possible, but a couple of ideas to get around it: