场景

针对远程 GitLab 仓库,同一台电脑有多个账号,比如 root 账号,权限较高,负责创建用户分组、仓库管理等;有的账号是开发账号,权限较低,仅对单一仓库具备权限。针对这种情况,就需要做一些特别设置。

原因

正常情况下如果是单账号,生成公私密钥对后,会将公钥保存至 GitLab 上,每次连接时 SSH 客户端发送本地私钥(默认~/.ssh/id_rsa)到服务端验证。在单账号情况下,连接的服务器上保存的公钥和发送的私钥自然是配对的。

但如果是多账号(假设一个是管理账号 root,一个是开发者账号 develop),当我们要连接 GitLab 上某远程仓库时,该远程仓库添加的是开发者账号 develop 的公钥,但是 SSH 客户端依然发送默认私钥,即 root 账号的私钥,那么这个验证自然无法通过。因此,要实现多帐号下的 SSH key 切换,就需要在客户端做一些配置。

解决方案

首先,在新增公私钥的时候,通过指定不同的目录以及文件名来存储不同的私钥文件。

  1. # ssh-keygen -t rsa -b 4096 -C "shimu@163.com"
  2. Generating public/private rsa key pair.
  3. Enter file in which to save the key (/Users/bgl/.ssh/id_rsa): /Users/bgl/.ssh/my_gitlab/gitlab

此处将公私钥保存至 .ssh/my_gitlab 目录下。 默认 SSH 只会读取 id_rsa,所以为了让 SSH 识别新的私钥,需要将其添加到 SSH agent。

ssh-add ~/.ssh/my_gitlab/gitlab

完成以上步骤后修改 ~/.ssh 目录下的 config 文件,该文件用于配置私钥对应的服务器。内容如下:

  1. # admin 账号
  2. Host admin
  3. HostName 121.46.135.249
  4. Port 42022
  5. IdentityFile ~/.ssh/id_rsa
  6. IdentitiesOnly yes
  7. # 开发者账号
  8. Host develop
  9. HostName 121.46.135.249
  10. Port 42022
  11. IdentityFile ~/.ssh/my_gitlab/gitlab
  12. IdentitiesOnly yes

其中:

  • Host 名称可随意,主要是方便自己记忆。但后续拉取远程仓库是需要使用 Host 的;
  • 在本项目中,GitLab 镜像是通过 Docker 来进行安装的,GitLab 镜像的 22 端口映射到了宿主机上的42022端口。所以需在 config 文件中指定 42022 端口。

配置完成后,在连接非默认帐号的 GitLab 仓库时,远程仓库的地址要对应地做一些修改。比如现在要拉取 GitLab 上 develop 账号下的远程仓库,则需运行如下命令:

git clone git@develop:fe-group/debug-jssdk.git

而非如下诸如此类命令:

git clone git@github.com:fe-group/debug-jssdk.git git clone git@121.46.135.249:42022:fe-group/debug-jssdk.git

这样每次连接都会使用 .ssh/my_gitlab/gitlab 下的密钥与服务器进行连接。至此,大功告成!

注意:

  • 在 GitLab 上的远程仓库配置了当前账号的公钥,但在拉取 GitLab 上的远程仓库,亦或者添加远程仓库地址( add remote origin )时,若中途出现要求输入密码情形,则造成这一情况的主要原因可能还是多账号之间的公私钥不匹配造成的,具体参照上述 config 文件的配置。

    1. # git clone git@121.46.135.249:42022:fe-group/debug-jssdk.git
    2. Cloning into 'debug-jssdk'...
    3. git@121.46.135.249's password:
  • GitLab 根据配置文件的user.email来获取 GitLab 帐号显示author信息,所以对于多帐号用户一定要记得将user.email 改为相应的email(develop@mail.com)。

参考链接