使用SSH协议 *************** SSH协议用于为Git提供远程读写操作,是远程写操作的标准服务,在智能HTTP协议\ 出现之前,甚至是写操作的唯一标准服务。 SSH协议语法格式 ================= 对于拥有shell登录权限的用户帐号,可以用下面的语法访问Git版本库: :: 语法1: ssh://[@][:]/path/to/repos/myrepo.git 语法2: [@]:/path/to/repos/myrepo.git 说明: * SSH协议地址格式可以使用两种不同的写法,第一种是使用\ ``ssh://``\ 开头\ 的SSH协议标准URL写法,另外一种是SCP格式的写法。 两种写法均可,SSH协议标准URL写法稍嫌复杂,但是对于非标准SSH端口(非22\ 端口),可以通过URL给出端口号。 * 是服务器上的用户帐号。 如果省略用户名,则缺省使用当前登录用户名(配置和使用了服务器别名除外)。 * 为SSH协议端口缺省为22。 端口只有在SSH协议标准URL写法可以给出,如果省略则使用缺省值22(配置和\ 使用了服务器别名除外)。 * :file:`/path/to/repos/myrepo.git`\ 是服务器中版本库的绝对路径。若用\ 相对路径则相对于username用户的主目录而言。 * 如果采用口令认证,不能像HTTPS协议那样可以在URL中同时给出登录名和口令,\ 必须每次连接时输入。 * 如果采用公钥认证,则无须输入口令。 服务架设方式比较 ================== 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服务的用户公钥。如:\ :file:`user1.pub`\ 、\ :file:`user2.pub`\ 。 * 使用\ :command:`ssh-copy-id`\ 命令远程将各个git用户的公钥加入服务器\ (server)的公钥认证列表中。 :: $ ssh-copy-id -i user1.pub anonymous@server $ ssh-copy-id -i user2.pub anonymous@server 如果直接在服务器上操作,则直接将文件追加到\ :file:`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服务器\ 软件的基础。 关于SSH公钥认证 ================== 关于公钥认证的原理,维基百科上的这个条目是一个很好的起点:\ http://en.wikipedia.org/wiki/Public-key_cryptography\ 。 如果用户的主目录下不存在\ :file:`.ssh`\ 目录,说明SSH公钥/私钥对尚未创建。\ 可以用这个命令创建: $ ssh-keygen 该命令会在用户主目录下创建\ :file:`.ssh`\ 目录,并在其中创建两个文件: * id_rsa 私钥文件。是基于RSA算法创建。该私钥文件要妥善保管,不要泄漏。 * id_rsa.pub 公钥文件。和\ :file:`id_rsa`\ 文件是一对儿,该文件作为公钥文件,可以公开。 创建了自己的公钥/私钥对后,就可以使用下面的命令,实现无口令登录远程服务\ 器,即用公钥认证取代口令认证。 :: $ ssh-copy-id -i .ssh/id_rsa.pub @ 说明: * 该命令会提示输入用户user在server上的SSH登录口令。 * 当此命令执行成功后,再以user用户登录server远程主机时,不必输入口令直接\ 登录。 * 该命令实际上将\ :file:`.ssh/id_rsa.pub`\ 公钥文件追加到远程主机server\ 的user主目录下的\ :file:`.ssh/authorized_keys`\ 文件中。 检查公钥认证是否生效,运行SSH到远程主机,正常的话应该直接登录成功。如果\ 要求输入口令则表明公钥认证配置存在问题。如果SSH登录存在问题,可以通过查\ 看服务器端的\ :file:`/var/log/auth.log`\ 日志文件进行诊断。 关于SSH主机别名 ================== 在实际应用中,有时需要使用多套公钥/私钥对,例如: * 使用默认的公钥访问git帐号,获取shell,进行管理员维护工作。 * 使用单独创建的公钥访问git帐号,执行git命令。 * 访问GitHub(免费的Git服务托管商)采用其他公钥。 首先要能够创建不同名称的公钥/私钥对。还是用\ :command:`ssh-keygen`\ 命令,如下: :: $ ssh-keygen -f ~/.ssh/ 注: * 将\ :file:``\ 替换为有意义的名称。 * 会在\ :file:`~/.ssh`\ 目录下创建指定的公钥/私钥对。 文件\ :file:``\ 是私钥,文件\ :file:`.pub`\ 是公钥。 将新生成的公钥添加到远程主机的\ :file:`.ssh/authorized_keys`\ 文件中,\ 建立新的公钥认证。例如: :: $ ssh-copy-id -i .ssh/.pub @ 这样,就有两个公钥用于登录主机server,那么当执行下面的ssh登录指令,用到\ 的是那个公钥呢? :: $ ssh @ 当然是默认公钥\ :file:`~/.ssh/id_rsa.pub`\ 。那么如何用新建的公钥连接\ server呢? SSH的客户端配置文件\ :file:`~/.ssh/config`\ 可以通过创建主机别名,在连接\ 主机时,使用特定的公钥。例如\ :file:`~/.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。 * 认证时使用的公钥文件为\ :file:`~/.ssh/jiangxin.pub`\ 。 .. SSH 服务器配置 .. -------------- .. .. TODO: /etc/ssh/sshd_config 设置某些用户的 SHELL .. .. TODO: 用 /etc/passwd 设置用户的shell .. .. TODO: 在 ~/.ssh/authorized_keys 用 command 设置用户的 shell