开发记录 (Git) - 经验: 为同一设备配置多个 SSH key 以对应不同的 Git 服务器

现在一个人同时有好几个 Git 账号或服务的情况越来越多,例如自己的私有仓库和公司的项目仓库分别在不同的 Git 服务器上。但是要用自己的同一台设备,重新生成 SSH key 会将之前的覆盖掉, 如何生成和管理多个 SSH key 呢?

步骤

假设在 ~/.ssh 目录下已经生成过密钥:id_rsaid_rsa.pub

  1. 生成第二个 SSH key

    和生成第一个命令相同:

    ssh-keygen -t rsa -C "youremail@example.com"

    这里不要一路回车,到输入路径提示时,填写保存路径(可以新建目录分别存放):

    Generating public/private rsa key pair.

    Enter file in which to save the key (/c/Users/xxx/.ssh/id_rsa): /c/Users/xxx/.ssh/id_rsa_gitlab

    后面的两步则为设置密码,可以直接回车跳过。

    这里的 id_rsa_gitlab 是可以自定义的,只要区别于原有的密钥名即可。

    完成之后就可以看到目录下多了两个文件:id_rsa_githubid_rsa_gitlab.pub

  2. 打开 ssh-agent

    如果使用 GitHub 官方的 bash ,输入:

    ssh-agent -s

    如果是其他的,例如常用的 Git Bash,输入:

    eval $(ssh-agent -s)

    略过此步骤,下一步会有错误提示:Could not open a connection to your authentication agent.

  3. 添加私钥

    分别输入命令:

    ssh-add ~/.ssh/id_rsa

    ssh-add ~/.ssh/id_rsa_gitlab

    如果提示文件或目录不存在,就使用绝对地址。

  4. ~/.ssh 目录下创建名为 config 的文件,后缀名为空;

    用文本编辑器打开后,添加以下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # github & gitlab
    # 注意:多个Host公用一个公钥时,对应的HostName和Port必须跟在Host后面
    # github
    Host coding1
    HostName github.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa

    # gitlab
    Host coding2
    HostName gitlab.ceair.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa_ceair
    User Git

    其中:Host 为主机名,可以自定义,但不能重复;HostName 主机的真实域名地址;PreferredAuthentications 是配置登录时使用的登录权限;IdentityFile 是私钥路径;User 是服务器账号名,不是自己的用户名,一般都是 Git;必要时,还需要添加 Port 属性,其默认值为 22。

    如果在 Linux 系统中有错误提示:Bad owner or permissions on /home/xxx/.ssh/config

    说明 config 权限过大,使用 chmod 命令调整:$ chmod 644 ~/.ssh/config

  5. 添加公钥

    在相应的 Git 服务页面中添加公钥,不赘述。

  6. 测试

    之前是直接输入 ssh -T git@github.com,现在则可以通过简称映射对应的域名和私钥,例如:

    ssh -T git@coding1

    而名为 coding2 的配置,设置了 User 属性,则可以简单输入 ssh -T coding2 完成测试。

    如果测试中收到错误提示:

    1
    2
    3
    The authenticity of host 'xxx (x.x.x.x)' can’t be established.
    RSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
    Are you sure you want to continue connecting (yes/no/[fingerprint])?

    则是因为新增的主机未添加至 know_hosts 文件中,输入 yes 回车即可。

    如果错误提示是:PTY allocation request failed on channel 0,则是因为将 -T 写成了小写。

调试

如果测试不成功,可以使用调试命令 --debug,例如测试 coding1:ssh -vT git@github.com`

命令 -v 是输出编译信息,然后根据信息可以排查编译中发生的错误。

使用

配置好多个 SSH key后,拉取代码时,需要将 SSH 地址做细微修改,才能用正确的用户去登陆验证。就是将对应域名(IP)换成 config 文件里配置的 Host 属性值即可。

例如原本的 SSH 地址为 `git@git.coding.net:master/DemoForSSH.git,需要修改为git@coding1:master/DemoForSSH.git再拉取即可。如果配置了User属性,SSH 地址可以简写为coding2:master/DemoForSSH.git`

拾遗

  1. 关于用户名

    如果之前设置了全局用户名和邮箱的话,需要取消一下:

    git config --global --unset user.name

    git config --global --unset user.email

    然后在不同的仓库下设置局部的用户名和邮箱,比如在公司的 repository 下:

    git config user.name "yourname"

    git config user.email "youremail"

    最后在自己的仓库重新执行刚刚的命令即可,这样就可以在不同的仓库,以不同的账号登录。

  2. 关于提交记录

    通过 SSH 拉取的代码,如果之前在 ~/.gitconfig 文件里配置过 user 信息,而又不想用全局的 user 信息,可以在当前工程里的 .git/config 文件里配置 user 信息,以便查看commit记录等,例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    [core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
    [user]
    name = yourname
    email = youremail@example.com
    [remote "origin"]
    url = xxx
    fetch = xxx
    [branch "master"]
    remote = origin
    merge = refs/heads/master
  1. 关于 TortoiseGit 中输错密码的处理:

    在控制面板中的“用户账户”设置中,找到“windows凭证管理”,在普通凭证中,删掉输错的对应项即可。

参考

参考1:https://zyoung.me/多账号SSH配置/

参考2:https://www.jianshu.com/p/f7f4142a1556