Luna Tech

Tutorials For Dummies.

自定义SSH key with Git

2019-11-09


0. 前言

上篇文章提到我在用custom ssh key pair操作GitHub repo的时候遇到了一些问题,经过各路朋友的指点,我发现了问题所在,并且成功解决了这个问题~

今天这篇文章就谈谈如何使用Custom ssh key pair来和server进行交互。

同时,我也研究了一下ssh-agent和ssh-add,感觉又学到了不少新东西~

Let’s get our hands dirty again!


1. 更改ssh config

首先,有朋友指出,我无法用custom key的原因是,by default,ssh会使用id_rsa这个key,如果想要override,就必须在ssh config里面做相应的修改。

于是,接着上一篇的内容,现在我们来修改ssh config。

Figure 1: change ssh config

sudo nano ~/.ssh/config

Figure 2: current ssh config

当我打开ssh config的时候发现,里面已经有Github host的相关内容了(不知道是什么时候加进去的= =反正不是我加的)。

如果想要用github这个custom ssh key的话,只要在这个文档的Host github.com最后加上IdentityFile ~/.ssh/github就行了。

Ctrl+X退出编辑模式,选择Y(更改文件)。

Figure 3: add IdentityFile line

保存之后再尝试git pull,我发现我的自定义ssh key生效了(因为我不用输passphrase了,我的default key是有设置过passphrase的)。

Figure 4: 成功用custom key pull project!


2. 多个SSH profile

我又继续开始思考,既然custom ssh key是可行的,那我其实可以给不同的Git cloud server设置不同的ssh key,比如GitHub用一个key,GitLab用一个key(喜欢折腾的我= =)。

下面是我的尝试:

1. 生成GitLab ssh key pair

# create a new ssh key for gitlab
ssh-keygen -t rsa -b 4096 -C "[email protected]"
# check new key pair
ls -al ~/.ssh

Figure 5-1: generate a key for GitLab

Figure 5-2: generate a key for GitLab

2. 把新的key pair加入到GitLab里面

# get content of the public key
cat ~/.ssh/gitlab.pub

Figure 6: get new public key

Figure 7: add new public key in GitLab


3. Temporarily use new key

如果你用的是default key,就不会遇到本文的第三部分和第四部分的问题(隐藏关卡哦~),因为我们不走寻常路,用的是一个custom key pair,所以才有了下面的乐趣。

我们先来说一下如何让custom key在当前的session生效。

注:我一开始以为需要先在authorized_key里面添加这个新的public key,但实际上不需要。

同时,第一篇文章有漏掉import environment variable的步骤。

1. Add private key to ssh agent

如果直接用ssh-add来添加这个key的话,会出现error。

Figure 8: ssh-add failed

Problem Solving: 我在查阅了资料之后了解到,需要先run eval $(ssh-agent)才可以run ssh-add

# correct way of adding new private key
# 1. import environment variable
eval "$(ssh-agent)"
# 2. add private key to ssh agent
ssh-add ~/.ssh/gitlab

Figure 9: ssh-add

2. what does eval do?

但是我又不懂了……为啥要run这个eval $(ssh-agent)?它到底在干嘛?

经过一番查询,查到了一个有用的回答,总结来说就是这个eval会把ssh-agent的environment variable import进来。

Figure 10: why run eval?

所以正确的操作流程是这样的:

Figure 11: process of adding private key

3. ssh-agent & ssh-add

**那么ssh-agent和ssh-add到底是什么关系呢?**为了搞清楚这两者的关系,我查到了这篇文章

文中提到,在Unix系统中,ssh-agent是用来管理ssh private key的一个程序,而ssh-add这个指令让我们可以把private key加入到ssh-agent程序所管理的key list里面。

当我们把一个ssh private key加入到ssh-agent的key list里面之后,在和host(比如GitHub, GitLab)进行交互的时候,就不用重复输入这个private key了(还记得吗?private key需要用来解密host发送过来的数据)。

所以简单来说,ssh-add是属于ssh-agent的一个command line tool。

Figure 12: relationship of ssh-agent and ssh-add

4. Clone project

Figure 13: get ssh link

Figure 14: successfully clone

Figure 15: successfully pull

但是注意!此时我其实没有在~/.ssh/config里面做任何的改动,之所以可以成功clone和pull是因为刚才我们把这个GitLab private key加入到了当前的环境变量里面

为了验证我这个想法,我重启了server。

Figure 16: reboot server

果然又出现了第一篇文章的那种奇特现象(第一次成功,后来却无法pull repo)。

想要永久使用GitLab这个custom key来操作repo,就必须要修改~/.ssh/config文件了。


4. 修改ssh config(永久生效)

那么config文件里要写啥呢?这就要去找官方的文档了。

在这一部分,有清楚的写到如何config。

Figure 17: official documentation from GitLab

Figure 18: ssh config updated

再次重启server,此时不需要进行ssh-add的操作,也可以去pull repo,因为这个配置已经永久存在我的ssh config里面了。

Figure 19: permanently add custom key

References

1. ssh-add problem: https://unix.stackexchange.com/questions/48863/ssh-add-complains-could-not-open-a-connection-to-your-authentication-agent

2. why run eval: https://unix.stackexchange.com/questions/351725/why-eval-the-output-of-ssh-agent

3. ssh-agent and ssh-add: https://kb.iu.edu/d/aeww

4. GitLab 文档: https://docs.gitlab.com/ee/ssh/

5. add custom ssh key for git: https://stackoverflow.com/questions/4565700/how-to-specify-the-private-ssh-key-to-use-when-executing-shell-command-on-git


5. 遗留的问题

1. ~/.ssh/authorized_keys

这个文件在我启动server后,里面包含两个key,一个是GitHub,一个是默认key,那。。为啥GitLab的key不在里面呢?(换言之,在什么情况下,这个文件里会有key?这些key是怎么加进去的?加进去是用来干嘛的?)

Figure 20: authorized_keys

我可以通过下面的指令手动加入GitLab的key,但是测试如果server重启这个key就消失了。

# add the new public key to authorized_keys
cat ~/.ssh/gitlab.pub ~/.ssh/authorized_keys

Figure 21: manually add another key

2. ~/.ssh/config

让我感觉奇怪的是,我第一次打开这个文档,里面是有GitHub的默认配置的(第一部分中,我直接在下面加了一行关于custom key的代码)。

但是,为啥我在配置GitLab的时候,这个file里面没有出现相关的内容……我是通过search GitLab custom ssh config才找到正确的配置代码的。

如果有读者可以解释以上两个问题,欢迎留言~文中如果有不对的地方也欢迎指出!