I have a little project going on where I have a custom PHP-script that is handling access tokens stored in a database (instead of regular authentication) and serving up different files. All of that has worked really good with regular files and, for example, Debian repos, but it doesn't seem to work with Git at all. I've done a git clone --bare
clone of the repo, and I can git clone
it directly from the server actually hosting the files (let's call it PrivateServer), but I cannot git clone
from the proxy server (ProxyServer).
A typical query to access some files with that script looks like the following:
https://my.proxyserver.com/download/a45d06774b61/repo/Packages
I would like my PHP-script to allow users to do git clone
. So far, it only allows them to view folders and do "regular" downloads.
Both servers are running Debian 9. PrivateServer is running Nginx, while ProxyServer is running Apache 2.4.
The Nginx redirect that is triggering the PHP-proxy script is as following:
rewrite ^/download/(..*)$ /proxy.php?$1 last;
On PrivateServer I'm using Apache. Here's my Apache conf:
<VirtualHost *:80>
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SetEnv GIT_PROJECT_ROOT /var/www/html/
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias ^/git/ /usr/libexec/git-core/git-http-backend/
RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
RewriteCond %{REQUEST_URI} /git-receive-pack$
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-core/git-http-backend/$1
<Directory "/usr/lib/git-core*">
Options +ExecCgi -MultiViews +SymLinksIfOwnerMatch
AllowOverride none
Order allow,deny
Allow from all
Require all granted
</Directory>
</VirtualHost>
This is the PHP-code of my proxy file:
<?php
function get_url($url)
{
$ch = curl_init();
if($ch === false)
{
die('Failed to create curl object');
}
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
# Define the variables we will be working with
$fulltoken = $_SERVER['QUERY_STRING']; #the whole string that follows the URL
$token = preg_replace("/\/.*$/","",$fulltoken); #Get just the auth-token
$suffix = str_replace("$token/","",$fulltoken); #the string after the auth-token
$suffix = preg_replace('/\&/','?',$suffix); #convert '&' to '?', for some reason the webserver seems to be replacing that one
/* Over here I have all the authentication functions inspecting the token in mysql, no trouble with those so I'm skipping them. */
if($auth_success) {
echo get_url("http://privateserver.com/$suffix");
} else {header: ("Status: 403");}
?>
This is what I get if I try to run git clone https://my.proxyserver.com/download/a45d06774b61/repo.git
fatal: https://my.proxyserver.com/download/a45d06774b61/repo.git/info/refs not valid: is this a git repository?
On PrivateServer (Apache):
GET /git/repo.git/info/refs?service=git-upload-pack HTTP/1.1" 200 660 "-" "-"
However, if I try to clone directly from PrivateServer, I get the following in Apache's logs:
"GET /git/repo.git/info/refs?service=git-upload-pack HTTP/1.1" 200 660 "-" "git/2.7.4"
"POST /git/repo.git/git-upload-pack HTTP/1.1" 200 8149 "-" "git/2.7.4"
So no errors, from what I can see.
I'm open for suggestions.