如何通过NGINX提供带有用户名/密码的HTTP GIT服务?

21
尽管我找到了许多关于如何配置git/nginx来获取我的存储库的链接,但我无法使它们运作。

我按照这个教程Git repository over HTTP WebDAV with nginx进行操作,但是用户/密码限制不起作用。任何人都可以克隆存储库。

之前我使用的是SVN + Apache + DAV_SVN配置,并且有一个用htpasswd创建的密码文件和一个用于权限控制的authz文件。我想要做同样的事情,使用git+nginx。这可能吗?

感谢您的帮助!

3个回答

22
请查看以下文章:http://www.toofishes.net/blog/git-smart-http-transport-nginx/,其中提供了一个nginx配置示例:
http {
    ...
    server {
        listen       80;
        server_name  git.mydomain.com;

        location ~ /git(/.*) {
            # fcgiwrap is set up to listen on this host:port
            fastcgi_pass  localhost:9001;
            include       fastcgi_params;
            fastcgi_param SCRIPT_FILENAME     /usr/lib/git-core/git-http-backend;
            # export all repositories under GIT_PROJECT_ROOT
            fastcgi_param GIT_HTTP_EXPORT_ALL "";
            fastcgi_param GIT_PROJECT_ROOT    /srv/git;
            fastcgi_param PATH_INFO           $1;
        }
    }
}

它所做的是将位于url中/gir之后的repo传递给 /usr/lib/git-core/git-http-backend。例如,http://git.mydomain.com/git/someapp 将指向 someapp 代码库。该仓库位于GIT_PROJECT_ROOTfastcgi_param 中定义为 /srv/git/someapp,可以更改以适应您的服务器。

这非常有用,您可以在nginx上应用HttpAuthBasicModule 来通过HTTP保护您的repo访问密码。

编辑:如果缺少git-http-backend,则可以在Ubuntu/Debian上安装git-core软件包,或者在基于RPM的平台上查看如何在CENTOS 5.5上安装git?


我按照这个例子在nginx上设置git。但是每次尝试克隆repo时,都会出现错误: “fatal: http://<ip>:9000/git/test.git/info/refs not valid: is this a git repository?”/var/log/nginx/error.log中没有错误,在访问日志中我可以看到:<my ip> - - [03/Oct/2015:08:35:42 +0200] "GET /git/test.git/info/refs?service=git-upload-pack HTTP/1.1" 200 424859 "-" "git/1.9.4.msysgit.1"你是否遇到过类似的问题? 谢谢, Janusz - Janusz Grabis
不要,但确保使用 git init --bare 创建了一个裸仓库。也就是说,不要托管检出的代码,除非你正在使用 git clone <repo> --bare。除此之外,谷歌应该可以帮到你。 - Mike Mackintosh
我最终找到了适合我的示例:http://serverfault.com/questions/483726/how-to-make-git-smart-http-transport-work-on-nginx。谢谢。 - Janusz Grabis
1
另外,在裸仓库上运行git update-server-info命令,这将生成一个.git/info/refs文件,以解决我遇到的404错误。 - ThorSummoner
1
在我的情况下,fcgi 没有监听任何端口,而是使用了 socket,我所要做的就是将 fastcgi_pass localhost:9001; 更改为 fastcgi_pass unix:/run/fcgiwrap.socket; - Galvani
显示剩余2条评论

20
这是一个完整的Git over HTTP配置,包括TLS加密、基本身份验证和GitWeb。我假设存储库的根目录在/home/git中。你应该将example.com替换为你的域名。
# Remove this block if you don't want TLS
server {
    listen 80;
    server_name git.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen       443 ssl; # Replace 443 ssl by 80 if you don't want TLS
    server_name  git.example.com;
    root         /usr/share/gitweb; # Remove if you don't want Gitweb

    error_log  /home/git/nginx-error.log;
    access_log /home/git/nginx-access.log;

    # Remove ssl_* lines if you don't want TLS
    ssl_certificate           /etc/letsencrypt/live/git.example.com/fullchain.pem;
    ssl_certificate_key       /etc/letsencrypt/live/git.example.com/privkey.pem;
    ssl_protocols             TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers               'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    # Remove auth_* if you don't want HTTP Basic Auth
    auth_basic "example Git";
    auth_basic_user_file /etc/nginx/.htpasswd;

    # static repo files for cloning over https
    location ~ ^.*\.git/objects/([0-9a-f]+/[0-9a-f]+|pack/pack-[0-9a-f]+.(pack|idx))$ {
        root /home/git/;
    }

    # requests that need to go to git-http-backend
    location ~ ^.*\.git/(HEAD|info/refs|objects/info/.*|git-(upload|receive)-pack)$ {
        root /home/git/;

        fastcgi_pass  unix:/var/run/fcgiwrap.socket;
        fastcgi_param SCRIPT_FILENAME   /usr/lib/git-core/git-http-backend;
        fastcgi_param PATH_INFO         $uri;
        fastcgi_param GIT_PROJECT_ROOT  $document_root;
        fastcgi_param GIT_HTTP_EXPORT_ALL "";
        fastcgi_param REMOTE_USER $remote_user;
        include fastcgi_params;
    }

    # Remove all conf beyond if you don't want Gitweb
    try_files $uri @gitweb;
    location @gitweb {
        fastcgi_pass  unix:/var/run/fcgiwrap.socket;
        fastcgi_param SCRIPT_FILENAME   /usr/share/gitweb/gitweb.cgi;
        fastcgi_param PATH_INFO         $uri;
        fastcgi_param GITWEB_CONFIG     /etc/gitweb.conf;
        include fastcgi_params;
   }
}

您需要安装 Git、Gitweb 和 FastCgiWrap:

sudo apt-get install git gitweb fcgiwrap

对于 TLS,我使用 Let's Encrypt 免费证书。

sudo letsencrypt certonly -d git.example.com --rsa-key-size 4096

要访问Gitweb,只需浏览到git.example.com。您还需要配置它以设置存储库的根目录:

sudo vim /etc/gitweb.conf

为了获得HTTP基本认证,您需要使用htpasswd命令将用户添加到/etc/nginx/.htpasswd中:
sudo apt-get install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd username

下一次运行命令时请删除-c开关,因为它只会创建文件(Nginx在其配置目录中默认没有.htpasswd文件)。
如果您想要更复杂、强大、类似于GitHub的东西,请查看Gitlab

1
我知道这是一个相当老的帖子,但我似乎无法让推送工作 - 它总是导致 504 错误。我只对您的配置进行了微小的调整。您是否曾经让它工作过? - Moritz Friedrich
是的,它之前是工作的(实际上现在仍然可以工作,但从那个回答以来就没有再碰过它了)。 - Morgan Touverey Quilling
你介意查一下你安装的fcgiwrap和git版本吗?如果你有机会来到德国,我愿意请你喝啤酒 :) - Moritz Friedrich
啊哈,我怎么能拒绝呢 :) -- git 2.11.0 / fcgiwrap 1.1.0 - Morgan Touverey Quilling
1
我最初在推送时也遇到了HTTP 504错误(网关超时);对我来说,这是由于权限问题引起的:fcgiwrap以用户“www-data”身份运行,但git存储库目录归另一个用户所有。 - Martin Dirichs

0

添加更多细节,我们需要3个组件:nginxgit-http-backendfcgiwrap

  • git-http-backend是一个独立的可执行二进制文件,可以从https://github.com/git/git构建。它是处理git http/https访问的官方解决方案,我不知道是否存在更好的解决方案。
  • Nginx没有内置的通用FastCGI服务器(或者我无法找到如何正确使用nginx的fastcgi_bind),因此应该使用另一个FastCGI服务器,例如fcgiwarp(一个很好的手册https://www.nginx.com/resources/wiki/start/topics/examples/fcgiwrap/
  • 在nginx配置中使用fastcgi_pass unix:/tmp/cgi.sock;(参考其他答案)

fastcgi不是必须的,git-http-backend也不仅限于fastcgi,而且fastcgi也不是最简单、性能最好的选择。 例如,我编写了一个servlet来在nginx和git-http-backend之间进行交互,使用了nginx的proxy_pass,它也可以正常工作!


能否分享一下你的proxy_pass设置? - Jazcash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接