內容目录

上一个主题

5.2. 使用Git协议

下一个主题

5.4. Gitolite服务架设

本页

5.3. 使用SSH协议

SSH协议用于为Git提供远程读写操作,是远程写操作的标准服务,在智能HTTP协议出现之前,甚至是写操作的唯一标准服务。

5.3.1. SSH协议语法格式

对于拥有shell登录权限的用户帐号,可以用下面的语法访问Git版本库:

语法1: ssh://[<username>@]<server>[:<port>]/path/to/repos/myrepo.git
语法2: [<username>@]<server>:/path/to/repos/myrepo.git

说明:

  • SSH协议地址格式可以使用两种不同的写法,第一种是使用ssh://开头的SSH协议标准URL写法,另外一种是SCP格式的写法。

    两种写法均可,SSH协议标准URL写法稍嫌复杂,但是对于非标准SSH端口(非22端口),可以通过URL给出端口号。

  • <username>是服务器<server>上的用户帐号。

    如果省略用户名,则缺省使用当前登录用户名(配置和使用了服务器别名除外)。

  • <port>为SSH协议端口缺省为22。

    端口只有在SSH协议标准URL写法可以给出,如果省略则使用缺省值22(配置和使用了服务器别名除外)。

  • /path/to/repos/myrepo.git是服务器中版本库的绝对路径。若用相对路径则相对于username用户的主目录而言。

  • 如果采用口令认证,不能像HTTPS协议那样可以在URL中同时给出登录名和口令,必须每次连接时输入。

  • 如果采用公钥认证,则无须输入口令。

5.3.2. 服务架设方式比较

SSH协议来实现Git服务,有如下方式:

  • 其一是用标准的ssh帐号访问版本库。即用户帐号可以直接登录到服务器,获得shell。

    对于这种使用标准SSH帐号方式,直接使用标准的SSH服务就可以了,无须赘述。

  • 另外的方式是,所有用户都使用同一个专用的SSH帐号访问版本库。各个用户通过公钥认证的方式用此专用SSH帐号访问版本库。而用户在连接时使用的不同的公钥可以用于区分不同的用户身份。

    Gitosis和Gitolite就是实现该方式的两个服务器软件。

标准SSH帐号和专用SSH帐号的区别见表29-1。

表29-1:不同SSH服务架设Git的对照

  标准SSH Gitosis/Gitolite
帐号 每个用户一个帐号 所有用户共用同一个帐号
认证方式 口令或公钥认证 公钥认证
用户是否能直接登录shell
安全性
管理员是否需要shell
版本库路径 相对路径或绝对路径 相对路径
授权方式 操作系统中用户组和目录权限 通过配置文件授权
对分支进行写授权 Gitolite
对路径进行写授权 Gitolite
架设难易度 简单 复杂

实际上,标准SSH,也可以用公钥认证的方式实现所有用户共用同一个帐号。不过这类似于把一个公共帐号的登录口令同时告诉给多个人。

  • 在服务器端(server)创建一个公共帐号,例如:anonymous。

  • 管理员收集需要访问git服务的用户公钥。如:user1.pubuser2.pub

  • 使用ssh-copy-id命令远程将各个git用户的公钥加入服务器(server)的公钥认证列表中。

    $ ssh-copy-id -i user1.pub anonymous@server
    $ ssh-copy-id -i user2.pub anonymous@server
    

    如果直接在服务器上操作,则直接将文件追加到authorized_keys文件中。

    $ cat /path/to/user1.pub >> ~anonymous/.ssh/authorized_keys
    $ cat /path/to/user2.pub >> ~anonymous/.ssh/authorized_keys
    
  • 在服务器端的anonymous用户主目录下建立git库,就可以实现多个用户利用同一个系统帐号(git)访问Git服务了。

这样做除了免除了逐一设置帐号,以及用户无需口令认证之外,标准SSH部署Git服务的缺点一个也不少,而且因为用户之间无法区分,更无法进行针对用户授权。

下面重点介绍一下SSH公钥认证,因为它们是后面介绍的Gitosis和Gitolite服务器软件的基础。

5.3.3. 关于SSH公钥认证

关于公钥认证的原理,维基百科上的这个条目是一个很好的起点:http://en.wikipedia.org/wiki/Public-key_cryptography

如果用户的主目录下不存在.ssh目录,说明SSH公钥/私钥对尚未创建。可以用这个命令创建:

$ ssh-keygen

该命令会在用户主目录下创建.ssh目录,并在其中创建两个文件:

  • id_rsa

    私钥文件。是基于RSA算法创建。该私钥文件要妥善保管,不要泄漏。

  • id_rsa.pub

    公钥文件。和id_rsa文件是一对儿,该文件作为公钥文件,可以公开。

创建了自己的公钥/私钥对后,就可以使用下面的命令,实现无口令登录远程服务器,即用公钥认证取代口令认证。

$ ssh-copy-id -i .ssh/id_rsa.pub <user>@<server>

说明:

  • 该命令会提示输入用户user在server上的SSH登录口令。
  • 当此命令执行成功后,再以user用户登录server远程主机时,不必输入口令直接登录。
  • 该命令实际上将.ssh/id_rsa.pub公钥文件追加到远程主机server的user主目录下的.ssh/authorized_keys文件中。

检查公钥认证是否生效,运行SSH到远程主机,正常的话应该直接登录成功。如果要求输入口令则表明公钥认证配置存在问题。如果SSH登录存在问题,可以通过查看服务器端的/var/log/auth.log日志文件进行诊断。

5.3.4. 关于SSH主机别名

在实际应用中,有时需要使用多套公钥/私钥对,例如:

  • 使用默认的公钥访问git帐号,获取shell,进行管理员维护工作。
  • 使用单独创建的公钥访问git帐号,执行git命令。
  • 访问GitHub(免费的Git服务托管商)采用其他公钥。

首先要能够创建不同名称的公钥/私钥对。还是用ssh-keygen命令,如下:

$ ssh-keygen -f ~/.ssh/<filename>

注:

  • <filename>替换为有意义的名称。
  • 会在~/.ssh目录下创建指定的公钥/私钥对。 文件<filename>是私钥,文件<filename>.pub是公钥。

将新生成的公钥添加到远程主机的.ssh/authorized_keys文件中,建立新的公钥认证。例如:

$ ssh-copy-id -i .ssh/<filename>.pub <user>@<server>

这样,就有两个公钥用于登录主机server,那么当执行下面的ssh登录指令,用到的是那个公钥呢?

$ ssh <user>@<server>

当然是默认公钥~/.ssh/id_rsa.pub。那么如何用新建的公钥连接server呢?

SSH的客户端配置文件~/.ssh/config可以通过创建主机别名,在连接主机时,使用特定的公钥。例如~/.ssh/config文件中的下列配置:

host bj
  user git
  hostname bj.ossxp.com
  port 22
  identityfile ~/.ssh/jiangxin

当执行

$ ssh bj

或者执行

$ git clone bj:path/to/repos/myrepo.git

含义为:

  • 登录的SSH主机为bj.ossxp.com
  • 登录时使用的用户名为git。
  • 认证时使用的公钥文件为~/.ssh/jiangxin.pub