多个密钥ssh-key的生成与管理

由于 Git 大文件以 https 协议传输较慢,而且每次还要输入用户名和密码,很是麻烦,而使用 ssh 协议传输的话,上面的问题都不会出现。如果你只有一个 Git 账号,建立 ssh 连接就很简单了,但是因为某些原因需要申请多个账号,比如公司和家里的电脑都需要使用 Git 服务,而 Github 官方网站规定了一对 ssh-key 只对应一个账号,一个账号可以存放多个公钥。你在一台电脑上要使用多个账号的话,必须要管理你的密钥,也就是指定使用哪个密钥。

最近在提交项目到 git 和 coding 时折腾了一天,现将我的解决思路总结如下:

生成密钥

在命令行中,键入

1
ssh-keygen -t rsa -C "your_email"

会生成一对密钥,默认情况下,私钥将放在 ~/.ssh/id_rsa,对应的公钥则为 ~/.ssh/id_rsa.pub。

生成的过程中,会询问你存放密钥的位置。第一次生成密钥时直接回车就行,则密钥放在 ~/.ssh/ 下,由于每个人可能不止需要一个密钥,所以可以另存为其他名字的密钥,比如 path/to/your/dir/coding_rsa,此时会生成对应的一对密钥。

可以使用以下代码来查看生成的公钥

1
cat ~/.ssh/coding_rsa.pub

也可以用记事本或文本编辑器打开查看,然后将公钥复制到你需要的服务器上(比如 github,gitlab,coding 等等)

密钥管理

如前文所述,如果我们需要多个密钥,那么在使用中,如何确定实际使用哪一个呢?

目前为止,ssh-key 用得最多的两个地方,一是 git 相关服务,二是远程连接服务器。

命令行输入:

1
2
ssh -i path/to/your/key developer@192.168.1.237 -p 23
scp -i path/to/your/key filename developer@192.168.1.237:/diskpath

用 -i 指定私钥,-p 指定端口,连接服务器

由于每个 git 账户都绑定了不同的公钥,每次提交时会发送本地私钥(默认~/.ssh/id_rsa)到服务端验证,多用户的话,这个验证自然无法通过。所以要通过 ~/.ssh/config 文件来控制。如果没有就在 ~/.ssh 目录下创建 config 文件,该文件用于配置密钥对应的服务器。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Default github user(first@mail.com)

Host github.com
HostName github.com
User git
IdentityFile C:/Users/username/.ssh/id_rsa

# test (second@mail.com)

Host github-second # 别名
HostName github.com
User git
IdentityFile C:/Users/username/.ssh/test

# coding.net user (third@mail.com)

Host git.coding.net
User third@email.com
PreferredAuthentications publickey
IdentityFile C:/Users/username/.ssh/coding_rsa

Host可以随意填写,但是我不建议这样做,假如有这样一个仓库地址:git@github.com:username/xxx.git,则HostName为github.com或该域名所指向的IP,并且Host最好填写github.com,为什么呢?因为当你在其它电脑上克隆仓库时,我们通常直接 copy 仓库地址,这时如果你的 Host 不是github.com而是随意填写的,克隆就会出错,只有把仓库地址里的github.com改为你填写的名称才能克隆成功,大家不相信的可以一试,另外需要注意的是如果你的项目所在网站地址栏出现端口号,而 copy 的仓库地址里却没有,这时以仓库地址为准,千万不要手欠给remote repository加上端口号,否则会出现Repo Not Found的情况。然后username 为你计算机的用户名,User后填写你的注册邮箱。

上述配置完成后,那么恭喜你可以进行日常的代码克隆拉取推送等操作了。

测试ssh

远程操作前也可以进行密钥的连通性测试:

1
ssh -T git@github.com

前段时间遇到一个诡异的问题:github突然连接不上,代码无法推送

1
2
connect to host github.com port 22: Connection timed out #一开始出现这个错误
ssh_exchange_identification: Connection closed by remote host #三次后出现这个

捣鼓了二个多小时,终于爬出了这个坑,方法如下:

1
2
3
4
5
6
Host github.com
HostName ssh.github.com
User youremail@xx.com #填上你自己的邮箱
PreferredAuthentications publickey
IdentityFile C:/Users/username/.ssh/id_rsa #username自己查看
Port 443

输入下列命令查看连接的详细信息

1
ssh -vT git@github.com

出现如下提示,表示这个ssh公钥已经通过了认证

1
Hi USERNAME! You've successfully authenticated, but github does not provide shell access.

测试 coding 的ssh

1
ssh -T git@git.coding.net

出现如下提示,表示提示连接成功

1
Coding.net Tips : [Hello USERNAME, You've connected to Coding.net via SSH successfully!]