Nginx搭建Git的Smart HTTP
我们一般通过SSH进行授权访问,通过git://进行无授权访问,但是还有一种协议可以同时实现以上两种方式的访问。设置Smart HTTP一般只需要在服务器上启用一个Git自带的名为git-http-backend的CGI脚本

我们一般通过 SSH 进行授权访问,通过 git:// 进行无授权访问,但是还有一种协议可以同时实现以上两种方式的访问。 设置 Smart HTTP 一般只需要在服务器上启用一个 Git 自带的名为 git-http-backend 的 CGI 脚本。 该 CGI 脚本将会读取由 git fetchgit push 命令向 HTTP URL 发送的请求路径和头部信息, 来判断该客户端是否支持 HTTP 通信(不低于 1.6.6 版本的客户端支持此特性)。 如果 CGI 发现该客户端支持智能(Smart)模式,它将会以智能模式与它进行通信, 否则它将会回落到哑(Dumb)模式下(因此它可以对某些老的客户端实现向下兼容)。

一、git-http-backend

默认安装git并不包含名为git-http-backend的CGI脚本。如果需要git-http-backend脚本,安装方式如下:

sudo yum -y install git-core

安装成功后 在 /usr/libexec/git-core目录下可以找到 git-http-backend文件。

二、fcgiwrap

安装 fcgiwrap

sudo yum -y install fcgiwrap

安装完成后,在/lib/systemd/system/目录有 fcgiwrap@.socket 和 fcgiwrap@.service两个文件,如果没有就按照下列配置创建:

fcgiwrap@.socket文件:

[Unit]
Description=fcgiwrap Socket

[Socket]
ListenStream=/run/fcgiwrap/fcgiwrap-%i.sock
RuntimeDirectory=fcgiwrap
SocketUser=%i
SocketMode=0777

[Install]
WantedBy=sockets.target

fcgiwrap@.service文件:

[Unit]
Description=Simple CGI Server
After=nss-user-lookup.target
Requires=fcgiwrap@%i.socket

[Service]
EnvironmentFile=/etc/sysconfig/fcgiwrap
ExecStart=/usr/sbin/fcgiwrap ${DAEMON_OPTS} -c ${DAEMON_PROCS}
User=nginx
Group=nginx

[Install]
Also=fcgiwrap@%i.socket

服务启动命令:

# fcgiwrap 开启开机自动启动
sudo systemctl enable fcgiwrap@1

# fcgiwrap 关闭开机自动启动
sudo systemctl disable fcgiwrap@1

# 开启 fcgiwrap 服务
sudo systemctl start fcgiwrap@1

# 停止 fcgiwrap
sudo systemctl stop fcgiwrap@1

# 关闭socket服务
sudo systemctl stop fcgiwrap@1.socket 

三、安装Nginx

sudo yum -y install nginx

四、HTTP Authentication

使用htpasswd生成账号、密码。

安装htpasswd

sudo yum -y install httpd-tools

创建passwd文件和生成账号

sudo touch /etc/nginx/passwd
sudo htpasswd /etc/nginx/passwd username
sudo htpasswd /etc/nginx/passwd username2

五、Nginx配置

# Example nginx + git HTTP Smart mode (git-http-backend) + HTTP Authentication + HTTPS redirect
 
server {
	listen 80;
	server_name git.example.com;
 
	# Redirect all non-HTTPS traffic to the HTTPS variant
	return 301 https://$host$request_uri;
}
 
server {
	listen  443;
 	server_name git.example.com;
 	
 	# The root here have nothing to do with your git repository path.
	root /data/www/html;
	index index.html;
 
  # Turn on ssl and set ssl params
  ssl on;
  ssl_certificate /etc/nginx/ssl/example.com.crt;
  ssl_certificate_key /etc/nginx/ssl/example.com.key;
 
	auth_basic            "Restricted";
	auth_basic_user_file  /etc/nginx/passwd;
 
	location ~ \.git {
    # Set chunks to unlimited, as the body's can be huge
		client_max_body_size			0;
 
		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	/srv/git;
		fastcgi_param	PATH_INFO		$uri;
	
		# Forward REMOTE_USER as we want to know when we are authenticated
		fastcgi_param	REMOTE_USER		$remote_user;
		fastcgi_pass	unix:/var/run/fcgiwrap/fcgiwrap-1.sock;
	}
}

六、其他事项

  1. Nginx运行账号需要有GIT_PROJECT_ROOT目录的读写权限。
  2. Nginx运行账号需要有/var/run/fcgiwrap/fcgiwrap-1.sock文件的读写权限,SocketMode=0777 可以解决这个问题。

最后修改于 2022-12-13

此篇文章的评论功能已经停用。