gitnginxfastcgi

Git returns fatal: git-http-push failed


I'm trying to host a Git repo using Nginx 0.8.52, with fcgiwrap wrapping git-http-backend. However, I constantly receive the following error (note the error at the end):

HGs-MacBook-Pro:git_dev hg$ GIT_CURL_VERBOSE=1 git push production master
* Couldn't find host git.example.org in the .netrc file; using defaults
* About to connect() to git.example.org port 443 (#0)
*   Trying 111.222.333.444...
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    start date: 2012-11-27 09:56:30 GMT
*    expire date: 2012-12-27 09:56:30 GMT
*    issuer: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET /info/refs?service=git-receive-pack HTTP/1.1
User-Agent: git/1.7.11.4
Host: git.example.org
Accept: */*
Pragma: no-cache

< HTTP/1.1 401 Unauthorized
< Server: nginx
< Date: Thu, 29 Nov 2012 01:42:21 GMT
< Content-Type: text/html
< Content-Length: 188
< Connection: close
< WWW-Authenticate: Basic realm="Restricted"
< 
* Closing connection #0
* Issue another request to this URL: 'https://admin@git.example.org/info/refs?service=git-receive-pack'
* Couldn't find host git.example.org in the .netrc file; using defaults
* About to connect() to git.example.org port 443 (#0)
*   Trying 111.222.333.444...
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* SSL re-using session ID
* SSL connection using DHE-RSA-AES256-SHA
* old SSL session ID is stale, removing
* Server certificate:
*    subject: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    start date: 2012-11-27 09:56:30 GMT
*    expire date: 2012-12-27 09:56:30 GMT
*    issuer: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    SSL certificate verify result: self signed certificate (18), continuing anyway.
* Server auth using Basic with user 'admin'
> GET /info/refs?service=git-receive-pack HTTP/1.1
Authorization: Basic YWRtaW46
User-Agent: git/1.7.11.4
Host: git.example.org
Accept: */*
Pragma: no-cache

< HTTP/1.1 401 Unauthorized
< Server: nginx
< Date: Thu, 29 Nov 2012 01:42:24 GMT
< Content-Type: text/html
< Content-Length: 188
< Connection: close
* Authentication problem. Ignoring this.
< WWW-Authenticate: Basic realm="Restricted"
* The requested URL returned error: 401
* Closing connection #0
Password for 'https://admin@git.example.org': 
* Couldn't find host git.example.org in the .netrc file; using defaults
* About to connect() to git.example.org port 443 (#0)
*   Trying 111.222.333.444...
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* SSL re-using session ID
* SSL connection using DHE-RSA-AES256-SHA
* old SSL session ID is stale, removing
* Server certificate:
*    subject: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    start date: 2012-11-27 09:56:30 GMT
*    expire date: 2012-12-27 09:56:30 GMT
*    issuer: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    SSL certificate verify result: self signed certificate (18), continuing anyway.
* Server auth using Basic with user 'admin'
> GET /info/refs?service=git-receive-pack HTTP/1.1
Authorization: Basic REMOVED
User-Agent: git/1.7.11.4
Host: git.example.org
Accept: */*
Pragma: no-cache

* The requested URL returned error: 404
* Closing connection #0
* Couldn't find host git.example.org in the .netrc file; using defaults
* About to connect() to git.example.org port 443 (#0)
*   Trying 111.222.333.444...
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* SSL re-using session ID
* SSL connection using DHE-RSA-AES256-SHA
* old SSL session ID is stale, removing
* Server certificate:
*    subject: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    start date: 2012-11-27 09:56:30 GMT
*    expire date: 2012-12-27 09:56:30 GMT
*    issuer: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    SSL certificate verify result: self signed certificate (18), continuing anyway.
* Server auth using Basic with user 'admin'
> GET /info/refs HTTP/1.1
Authorization: Basic REMOVED
User-Agent: git/1.7.11.4
Host: git.example.org
Accept: */*
Pragma: no-cache

< HTTP/1.1 200 OK
< Server: nginx
< Date: Thu, 29 Nov 2012 01:42:32 GMT
< Content-Type: text/plain
< Connection: close
< Expires: Fri, 01 Jan 1980 00:00:00 GMT
< Pragma: no-cache
< Cache-Control: no-cache, max-age=0, must-revalidate
< Content-Length: 59
< 
* Closing connection #0
* Couldn't find host git.example.org in the .netrc file; using defaults
* About to connect() to git.example.org port 443 (#0)
*   Trying 111.222.333.444...
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* SSL re-using session ID
* SSL connection using DHE-RSA-AES256-SHA
* old SSL session ID is stale, removing
* Server certificate:
*    subject: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    start date: 2012-11-27 09:56:30 GMT
*    expire date: 2012-12-27 09:56:30 GMT
*    issuer: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    SSL certificate verify result: self signed certificate (18), continuing anyway.
* Server auth using Basic with user 'admin'
> GET /HEAD HTTP/1.1
Authorization: Basic REMOVED
User-Agent: git/1.7.11.4
Host: git.example.org
Accept: */*
Pragma: no-cache

< HTTP/1.1 200 OK
< Server: nginx
< Date: Thu, 29 Nov 2012 01:42:36 GMT
< Content-Type: text/plain
< Connection: close
< Expires: Fri, 01 Jan 1980 00:00:00 GMT
< Pragma: no-cache
< Cache-Control: no-cache, max-age=0, must-revalidate
< Content-Length: 23
< Last-Modified: Wed, 28 Nov 2012 12:09:23 +0000
< 
* Closing connection #0
Password for 'https://admin@git.example.org': 
* Couldn't find host git.example.org in the .netrc file; using defaults
* About to connect() to git.example.org port 443 (#0)
*   Trying 111.222.333.444...
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*    subject: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    start date: 2012-11-27 09:56:30 GMT
*    expire date: 2012-12-27 09:56:30 GMT
*    issuer: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    SSL certificate verify result: self signed certificate (18), continuing anyway.
> PROPFIND / HTTP/1.1
User-Agent: git/1.7.11.4
Host: git.example.org
Accept: */*
Depth: 0
Content-Type: text/xml
Content-Length: 161
Expect: 100-continue

< HTTP/1.1 401 Unauthorized
< Server: nginx
< Date: Thu, 29 Nov 2012 01:42:43 GMT
< Content-Type: text/html
< Content-Length: 188
< Connection: close
< WWW-Authenticate: Basic realm="Restricted"
< 
* Excess found in a non pipelined read: excess = 188 url = / (zero-length body)
* Closing connection #0
* Issue another request to this URL: 'https://admin@git.example.org/'
* Couldn't find host git.example.org in the .netrc file; using defaults
* About to connect() to git.example.org port 443 (#0)
*   Trying 111.222.333.444...
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* Connected to git.example.org (111.222.333.444) port 443 (#0)
* SSL re-using session ID
* SSL connection using DHE-RSA-AES256-SHA
* old SSL session ID is stale, removing
* Server certificate:
*    subject: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    start date: 2012-11-27 09:56:30 GMT
*    expire date: 2012-12-27 09:56:30 GMT
*    issuer: C=GB; ST=Berkshire; L=Newbury; O=My Company Ltd
*    SSL certificate verify result: self signed certificate (18), continuing anyway.
* Server auth using Basic with user 'admin'
> PROPFIND / HTTP/1.1
Authorization: Basic REMOVED
User-Agent: git/1.7.11.4
Host: git.example.org
Accept: */*
Depth: 0
Content-Type: text/xml
Content-Length: 161
Expect: 100-continue

< HTTP/1.1 100 Continue
* We are completely uploaded and fine
* The requested URL returned error: 404
* Closing connection #0
error: Cannot access URL https://admin@git.example.org/, return code 22
fatal: git-http-push failed

The backend fcgiwrap also complains in the log as follows:

Request not supported: '/home/admin/repo/info/refs?service=git-receive-pack'

During that same period, Nginx reports error logs of the following (which appears normal given the requests that Git push is sending):

2012/11/29 09:52:42 [error] 15091#0: *3257838 no user/password was provided for basic authentication, client: 222.055.121.111, server: git.example.org, request: "GET /info/refs?service=git-receive-pack HTTP/1.1", host: "git.example.org"
2012/11/29 09:52:45 [error] 15092#0: *3257989 user "admin": password mismatch, client: 222.055.121.111, server: git.example.org, request: "GET /info/refs?service=git-receive-pack HTTP/1.1", host: "git.example.org"
2012/11/29 09:53:02 [error] 15090#0: *3258816 no user/password was provided for basic authentication, client: 222.055.121.111, server: git.example.org, request: "PROPFIND / HTTP/1.1", host: "git.example.org"

For the sake of completeness, here is the relevant portion of nginx.conf:

# Git
server {
    listen 80;
    listen 443 ssl;
    server_name git.example.org;

    access_log  /home/admin/repo.deploy.log combined;
    ssl_certificate /etc/nginx/git.myserver.org.self.crt;
    ssl_certificate_key /etc/nginx/git.myserver.org.self.key;

    location / {
        auth_basic  "Restricted";
        auth_basic_user_file /etc/nginx/nginx.htpasswd;

        include fastcgi_params;

        fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend;
        fastcgi_param GIT_HTTP_EXPORT_ALL "";
        fastcgi_param GIT_PROJECT_ROOT /home/admin/repo/;
        fastcgi_param PATH_INFO $request_uri;

        fastcgi_pass 127.0.0.1:9001;
    }
}

Solution

  • The answer to this question is PATH_INFO was expecting $uri not $remote_uri

    Replacing:

    fastcgi_param PATH_INFO $request_uri;

    with

    fastcgi_param PATH_INFO $uri;

    Fixed the problem. I also added fastcgi_param REMOTE_USER $remote_user; as I was using http authentication.

    So it should look like this:

    # Git
    server {
        listen 80;
        listen 443 ssl;
        server_name git.myserver.org;
    
        access_log  /home/admin/repo.deploy.log combined;
        ssl_certificate /etc/nginx/git.myserver.org.self.crt;
        ssl_certificate_key /etc/nginx/git.myserver.org.self.key;
    
        location / {
            auth_basic  "Restricted";
            auth_basic_user_file /etc/nginx/nginx.htpasswd;
    
            include fastcgi_params;
    
            fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend;
            fastcgi_param GIT_HTTP_EXPORT_ALL "";
            fastcgi_param GIT_PROJECT_ROOT /home/admin/repo/;
            fastcgi_param PATH_INFO $uri;
            fastcgi_param REMOTE_USER $remote_user;
    
            fastcgi_pass 127.0.0.1:9001;
        }
    }