Git Server部署(基础)
架设 Git 服务最复杂的地方在于用户管理。
Git Server概述
协议介绍部分内容摘抄于:"https://git-scm.com/book/zh/v2/服务器上的-Git-协议"
1. 什么是Git Server
- 简介
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开源的分布式版本控制系统。而Git Server就是一个共享的版本仓库。 - Git Server支持的协议
git、ssh、https、file(Local protocol)
2. 本地协议
- 简述
最基本的就是本地协议(Local protocol),所谓的远程仓库在该协议中的表示,就是硬盘上的另一个目录。这常见于团队每一个成员都对一个共享的文件系统(例如 NFS)拥有访问权,或者比较少见的多人共用同一台电脑的情况。后面一种情况并不安全,因为所有代码仓库实例都储存在同一台电脑里,增加了灾难性数据损失的可能性。 - 例子
如果你使用一个共享的文件系统,就可以在一个本地文件系统中克隆仓库,推送和获取。克隆的时候只需要将远程仓库的路径作为 URL 使用,比如下面这样:
$ git clone /opt/git/project.git
或者这样:
$ git clone file:///opt/git/project.git
- 如果在 URL 开头明确的指定
file://
,那么 Git 的行为会略有不同。 如果仅是指定路径,Git 会尝试使用硬链接(hard link)或直接复制所需要的文件。 如果指定file://
,Git 会触发平时用于网路传输资料的进程,那通常是传输效率较低的方法。 指定file://
的主要目的是取得一个没有外部参考(extraneous references)或对象(object)的干净版本库副本– 通常是在从其他版本控制系统导入后或一些类似情况需要这么做。 在此我们将使用普通路径,因为这样通常更快。
- 如果在 URL 开头明确的指定
- 要添加一个本地仓库作为现有 Git 项目的远程仓库,可以这样做:
$ git remote add local_proj /opt/git/project.git
然后就可以像在网络上一样向这个远程仓库推送和获取数据了。 - 优点
基于文件仓库的优点在于它的简单,同时保留了现存文件的权限和网络访问权限。如果你的团队已经有一个全体共享的文件系统,建立仓库就十分容易了。你只需把一份裸仓库的副本放在大家都能访问的地方,然后像对其他共享目录一样设置读写权限就可以了。我们将在下一节“在服务器上部署 Git ”中讨论如何导出一个裸仓库的副本。
这也是从别人工作目录中获取工作成果的快捷方法。假如你和你的同事在一个项目中合作,他们想让你检出一些东西的时候,运行类似 git pull /home/john/project 通常会比他们推送到服务器,而你再从服务器获取简单得多。 - 缺点
这种方法的缺点是,与基本的网络连接访问相比,难以控制从不同位置来的访问权限。如果你想从家里的笔记本电脑上推送,就要先挂载远程硬盘,这和基于网络连接的访问相比更加困难和缓慢。
另一个很重要的问题是该方法不一定就是最快的,尤其是对于共享挂载的文件系统。本地仓库只有在你对数据访问速度快的时候才快。在同一个服务器上,如果二者同时允许 Git 访问本地硬盘,通过 NFS 访问仓库通常会比 SSH 慢。
3. SSH 协议
- 简述
架设 Git 服务器时常用 SSH 协议作为传输协议。 因为大多数环境下已经支持通过 SSH 访问 —— 即时没有也比较很容易架设。 SSH 协议也是一个验证授权的网络协议;并且,因为其普遍性,架设和使用都很容易。 - 例子
通过 SSH 克隆一个 Git 仓库,你可以像下面这样给出ssh://
的 URL:
$ git clone ssh://user@server/project.git
或者不指明某个协议 — 这时 Git 会默认使用 SSH :
$ git clone user@server:project.git
如果不指明用户,Git 会默认使用当前登录的用户名连接服务器。 - 优势
用 SSH 协议的优势有很多。 首先,SSH 架设相对简单 —— SSH 守护进程很常见,多数管理员都有使用经验,并且多数操作系统都包含了它及相关的管理工具。 其次,通过 SSH 访问是安全的 —— 所有传输数据都要经过授权和加密。 最后,与 HTTP/S 协议、Git 协议及本地协议一样,SSH 协议很高效,在传输前也会尽量压缩数据。 - 缺点
SSH 协议的缺点在于你不能通过他实现匿名访问。 即便只要读取数据,使用者也要有通过 SSH 访问你的主机的权限,这使得 SSH 协议不利于开源的项目。 如果你只在公司网络使用,SSH 协议可能是你唯一要用到的协议。 如果你要同时提供匿名只读访问和 SSH 协议,那么你除了为自己推送架设 SSH 服务以外,还得架设一个可以让其他人访问的服务。
4. Git 协议
- 简述
接下来是 Git 协议。 这是包含在 Git 里的一个特殊的守护进程;它监听在一个特定的端口(9418),类似于 SSH 服务,但是访问无需任何授权。 要让版本库支持 Git 协议,需要先创建一个 git-daemon-export-ok 文件 —— 它是 Git 协议守护进程为这个版本库提供服务的必要条件 —— 但是除此之外没有任何安全措施。 要么谁都可以克隆这个版本库,要么谁也不能。 这意味着,通常不能通过 Git 协议推送。 由于没有授权机制,一旦你开放推送操作,意味着网络上知道这个项目 URL 的人都可以向项目推送数据。 不用说,极少会有人这么做。 - 优点
目前,Git 协议是 Git 使用的网络传输协议里最快的。 如果你的项目有很大的访问量,或者你的项目很庞大并且不需要为写进行用户授权,架设 Git 守护进程来提供服务是不错的选择。 它使用与 SSH 相同的数据传输机制,但是省去了加密和授权的开销。 - 缺点
Git 协议缺点是缺乏授权机制。 把 Git 协议作为访问项目版本库的唯一手段是不可取的。 一般的做法里,会同时提供 SSH 或者 HTTPS 协议的访问服务,只让少数几个开发者有推送(写)权限,其他人通过 git:// 访问只有读权限。 Git 协议也许也是最难架设的。 它要求有自己的守护进程,这就要配置 xinetd 或者其他的程序,这些工作并不简单。 它还要求防火墙开放 9418 端口,但是企业防火墙一般不会开放这个非标准端口。 而大型的企业防火墙通常会封锁这个端口。
5. HTTP/S 协议
- 简述
Git 通过 HTTP 通信有两种模式。 在 Git 1.6.6 版本之前只有一个方式可用,十分简单并且通常是只读模式的。 Git 1.6.6 版本引入了一种新的、更智能的协议,让 Git 可以像通过 SSH 那样智能的协商和传输数据。 之后几年,这个新的 HTTP 协议因为其简单、智能变的十分流行。 新版本的 HTTP 协议一般被称为“智能” HTTP 协议,旧版本的一般被称为“哑” HTTP 协议。 我们先了解一下新的“智能” HTTP 协议。 - 智能(Smart) HTTP 协议
“智能” HTTP 协议的运行方式和 SSH 及 Git 协议类似,只是运行在标准的 HTTP/S 端口上并且可以使用各种 HTTP 验证机制,这意味着使用起来会比 SSH 协议简单的多,比如可以使用 HTTP 协议的用户名/密码的基础授权,免去设置 SSH 公钥。- 智能 HTTP 协议或许已经是最流行的使用 Git 的方式了,它即支持像 git:// 协议一样设置匿名服务,也可以像 SSH 协议一样提供传输时的授权和加密。 而且只用一个 URL 就可以都做到,省去了为不同的需求设置不同的 URL。 如果你要推送到一个需要授权的服务器上(一般来讲都需要),服务器会提示你输入用户名和密码。 从服务器获取数据时也一样。
- 事实上,类似 GitHub 的服务,你在网页上看到的 URL (比如, https://github.com/schacon/simplegit[]),和你在克隆、推送(如果你有权限)时使用的是一样的。
- 哑(Dumb) HTTP 协议
如果服务器没有提供智能 HTTP 协议的服务,Git 客户端会尝试使用更简单的“哑” HTTP 协议。 哑 HTTP 协议里 web 服务器仅把裸版本库当作普通文件来对待,提供文件服务。 哑 HTTP 协议的优美之处在于设置起来简单。 基本上,只需要把一个裸版本库放在 HTTP 根目录,设置一个叫做 post-update 的挂钩就可以了(见 Git 钩子)。 此时,只要能访问 web 服务器上你的版本库,就可以克隆你的版本库。- 下面是设置从 HTTP 访问版本库的方法:
$ cd /var/www/htdocs/ $ git clone --bare /path/to/git_project gitproject.git $ cd gitproject.git $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update
- 这样就可以了。 Git 自带的 post-update 挂钩会默认执行合适的命令(git update-server-info),来确保通过 HTTP 的获取和克隆操作正常工作。 这条命令会在你通过 SSH 向版本库推送之后被执行;然后别人就可以通过类似下面的命令来克隆:
$ git clone https://example.com/gitproject.git
- 这里我们用了 Apache 里设置了常用的路径 /var/www/htdocs,不过你可以使用任何静态 web 服务器 —— 只需要把裸版本库放到正确的目录下就可以。 Git 的数据是以基本的静态文件形式提供的(详情见 Git 内部原理)。
- 这样就可以了。 Git 自带的 post-update 挂钩会默认执行合适的命令(git update-server-info),来确保通过 HTTP 的获取和克隆操作正常工作。 这条命令会在你通过 SSH 向版本库推送之后被执行;然后别人就可以通过类似下面的命令来克隆:
- 下面是设置从 HTTP 访问版本库的方法:
- 通常的,会在可以提供读/写的智能 HTTP 服务和简单的只读的哑 HTTP 服务之间选一个。 极少会将二者混合提供服务。
- 优点
我们将只关注智能 HTTP 协议的优点。- 不同的访问方式只需要一个 URL 以及服务器只在需要授权时提示输入授权信息,这两个简便性让终端用户使用 Git 变得非常简单。 相比 SSH 协议,可以使用用户名/密码授权是一个很大的优势,这样用户就不必须在使用 Git 之前先在本地生成 SSH 密钥对再把公钥上传到服务器。 对非资深的使用者,或者系统上缺少 SSH 相关程序的使用者,HTTP 协议的可用性是主要的优势。 与 SSH 协议类似,HTTP 协议也非常快和高效。
- 你也可以在 HTTPS 协议上提供只读版本库的服务,如此你在传输数据的时候就可以加密数据;或者,你甚至可以让客户端使用指定的 SSL 证书。
- 另一个好处是 HTTP/S 协议被广泛使用,一般的企业防火墙都会允许这些端口的数据通过。
-
缺点
-
在一些服务器上,架设 HTTP/S 协议的服务端会比 SSH 协议的棘手一些。 除了这一点,用其他协议提供 Git 服务与 “智能” HTTP 协议相比就几乎没有优势了。
-
如果你在 HTTP 上使用需授权的推送,管理凭证会比使用 SSH 密钥认证麻烦一些。 然而,你可以选择使用凭证存储工具,比如 OSX 的 Keychain 或者 Windows 的凭证管理器。 参考 凭证存储 如何安全地保存 HTTP 密码。
-
部署Git服务器
这里采用ssh协议配置
1.安装git
- git客户端和服务器是同一个安装包,以centos为例:
root# yum install git
2. 配置git用户/组
-
创建git Group
[root@centos ~]# groupadd -g 10001 git
-
创建git User
创建git用户后,可以设置密码,也可以不设置密码,为了安全这里不设置密码 ,采用ssh key的方式远程登录
[root@centos ~]# useradd -u 10001 -g git git
-
将自己的用户加入git组(非必要)
方便管理git服务器的文件
$ sudo usermod -a -G git username
3. key验证登录
-
客户端创建key
[dream@Mint ~]$ ssh-keygen -t rsa 可以愉快的一路回车,也可以设个密码啥的...... [dream@Mint ~]$ ls .ssh // id_rsa为私钥,id_rsa.pub是公钥 config id_rsa id_rsa.pub known_hosts
-
服务器端配置git用户家目录的
.ssh/authorized_keys
文件-
client端上传公钥
[dream@Mint .ssh]$ scp id_rsa.pub 192.168.1.10:/tmp
-
Server端git用户配置
[git@centos ~]$ mkdir .ssh [git@centos ~]$ touch .ssh/authorized_keys [git@centos ~]$ chmod -R 700 .ssh [git@centos ~]$ chmod 600 .ssh/authorized_keys [git@centos ~]$ cat /tmp/id_rsa.pub >> .ssh/authorized_keys //将所有需要推送权限的用户的key的公钥全部导入该文件
-
-
验证
[dream@Mint ~]$ ssh git@192.168.1.10 Last login: Wed Jul 5 23:17:28 2017 from 192.168.1.19 Welcome to Alibaba Cloud Elastic Compute Service ! [git@centos ~]$
4. 安全配置
-
修改git用户的shell禁止登录终端
# usermod -s `which git-shell` git //使用的是反引号
-
git-shell问题
git用户配置了git-shell登录后,需配置一个git-shell-commands,否则不能登录git,只需要拷贝git-shell-commands文件,以及修改权限[root@centos ~]# su - git //登录失败 Last login: Sun Jun 4 13:21:08 CST 2017 on pts/0 fatal: Interactive git shell is not enabled. hint: ~/git-shell-commands should exist and have read and execute access. [root@centos ~]# [root@centos ~]# cp -r /usr/share/doc/git-1.8.3.1/contrib/git-shell-commands/ /home/git/ //拷贝git-shell-commands文件夹到git用户家目录,其中git-1.8.3.1是git版本号 [root@centos ~]# chown -R git:git /home/git/git-shell-commands/ //修改文件所属 [root@centos ~]# chmod +x /home/git/git-shell-commands/* //添加文件的执行权限 [root@centos ~]# su - git Last login: Sun Jun 4 13:47:21 CST 2017 on pts/0 Run 'help' for help, or 'exit' to leave. Available commands: README list git> exit
-
ssh再次登录验证
[dream@Mint ~]$ ssh git@192.168.1.10 Last login: Wed Jul 5 23:17:28 2017 from 192.168.1.19 Welcome to Alibaba Cloud Elastic Compute Service ! Run 'help' for help, or 'exit' to leave. Available commands: list README git>
-
建议使用ssh时的一些文件权限
- 用户的家目录:755
.ssh
目录:700- 公钥文件
authorized_keys
:600
创建Git共享仓库
1. 服务器创建Git共享仓库
- 创建仓库目录,不建议将仓库放在某个用户的home目录
# mkdir -p /data/repository.git
- 初始化Git仓库(目录)
# git init --bare /data/repository.git
--bare
参数是创建裸仓库,裸仓库是没有工作区的
- 更改Git仓库的文件权限
# chown -R git:git /data/repository.git
# chmod -R 700 /data/repository.git
2. 客户端克隆仓库
$ git clone git@xxx.xxx.xxx.xxx/data/repository.git
附:
- 要方便管理公钥,用Gitosis;
- 要像SVN那样变态地控制权限,用Gitolite。
Git Server之git hook(进阶)
实现web代码的自动部署
一般的web项目,
实现的功能:
在本地开发,然后推送到Server端的Git仓库,并自动同步到web站点目录,达到在本地推送完即可看到网页的效果,简言之就是实现自动同步的功能。
对于文档/文库的站点,还可以直接在web端编辑文档,并提交以及推送到Server端的git仓库
这里的git仓库和web站点可以在一个OS中,也可以在不同的OS中
后期更新。。。