今天把博客文章上传的流程优化了一下,之前我是本地把project push到GitHub,然后Server通过HTTPS来pull change,但是这个流程的问题在于每次pull change都要输一遍GitHub的用户名密码,为了省掉输入信息的时间,我今天在Server生成了SSH Key pair,通过SSH链接来操作GitHub repo,实现了效率的提升~
本文会介绍SSH协议,SSH Key pair的一些原理,以及我的具体操作步骤。
在没有配置SSH之前,我是无法通过ssh链接来clone GitHub project的,显示Permission Denied。
按照惯例,所有的SSH key都存在你系统的根目录下,一个.ssh
的隐藏文件夹。
注:这里我采用的是Linux server作为例子(MacOS也一样,直接在Terminal操作即可),Windows用户需要下载PuTTy。
|
|
|
|
/home/lunawen/.ssh/github
,也就是在/home/lunawen/.ssh
这个文件夹里面生成一个叫做github
的ssh key。更新:这一步建议大家还是用default的key,因为我后来遇到了奇怪的问题……
如果这一步你输入了passphrase的话,下面把SSH key加入SSH Agent的时候也需要用到这个passphrase,所以要记住哦~
这一步完成后,我们的ssh文件夹中会新增两个文件——github
和github.pub
。
|
|
为什么会有两个文件呢?
如果你也有这样的疑问,就先跟我一起了解一下SSH以及SSH key的原理吧~
SSH全称Secure Shell,于1995年出生,它的目的是让两台电脑之间的连接更加安全;打比方就是两个人说话的时候,SSH协议可以保护他们的谈话内容不被别人窃听。
怎么做到呢?简而言之,两台电脑通过SSH协议连接之后,他们之间的所有沟通都是被加密过的,所以就算别人听到了,没法解密的话,也听不懂= =。
用SSH协议传输文件的时候,实际用的是建立于SSH协议上的SFTP(SSH File Transfer Protocol),比常见的FTP要安全很多。
SSH的默认端口是22,要建立SSH连接必须保证SSH的端口开放哦~
想要改变默认端口也是可以的,Linux系统可以通过
sudo vi /etc/ssh/sshd_config
这个指令去修改默认配置,这里不做展开,有兴趣的可以看这篇文章。
SSH Key的全称是Secure Shell Keys,SSH Keys是成对出现的,作用是让电脑和电脑之间建立可信赖的关系。
打个比方,现实生活中,每扇门都有一个锁,和至少一把钥匙;
而在计算机的世界里,SSH keys就是给两台电脑“配对”的媒介,SSH Key的Private Key就相当于门上的那把锁,只有持有配对的钥匙(Public Key)才能打开那把锁。
你可以给自己信赖的人发放钥匙(Public Key)邀请他们到你家来玩,但是如果你的Private Key(门上的锁)丢了或者换了,这扇门就不可能被原来的钥匙(Public Key)打开。
具体的配对过程跟非对称加密算法有关,在此不做展开。
另外,和现实生活中类似的是,SSH Keys有不同的size(就像我们的钥匙大小形状也不一样),最常用的一种是RSA 2048-bit encryption。
SSH Agent是一个用来管理用户SSH key的程序;每台电脑可以有多个SSH key pair。
|
|
经过前面的背景知识补充,你应该明白为什么我们一开始生成SSH Key的时候会得到两个不同的文件了,那个github.pub
就是public key,如果其他电脑持有这个public key,他们就可以跟你的电脑建立连接。
现在我们需要做的是,让GitHub和我们的Server建立友好关系,这样我们就不用在每次pull repo的时候输入用户名密码了(节约了打字时间哦!)。
|
|
登录GitHub -> 进入Settings界面 -> 选择SSH and GPG keys。
新建SSH Key。
之前我们是无法通过SSH来操作GitHub Repo的,而如果通过HTTPS的连接来操作Repo,每次都需要输入用户名密码。
现在,当我们完成了GitHub Public Key的配置之后,我们可以直接通过SSH来进行操作啦~
假如我要Clone这个project,首先要切换到SSH的选项:
然后只要用git clone ssh-link
就可以直接Clone了(无用户名密码输入过程)。
同理,在这个project里面使用任何的git command(如git pull
),都不需要再次验证你的身份。
是不是方便很多呀!😎
下面的图总结了我们之前完成的几个步骤:
那么,为什么我们不用输用户名密码了呢??
SSH到底是通过什么流程来进行验证的呢?
在实际体会到SSH的便利后,让我们来深入了解一下刚才到底发生了什么:
这篇文章本来是周六就写完的,但是在发布文章的时候,我突然发现,我在remote server执行git pull的时候遇到了Permission Error……
这不是打脸了吗……明明文章是关于ssh的设置,到最后还是没有设置成功……最让我百思不得其解的是,之前明明是可以用的啊(不然我是怎么截的图……),第二次就不行了???
经过了漫长的trouble shooting过程,看了很多文章,还是不明白为啥会有这个问题……
对比了我的操作过程和官方教程,发现唯一的区别可能是我没有用默认的id_rsa
文件来做配置,而是自己重新生成了一个github key pair。
于是我尝试把默认的public key加入了GitHub的SSH key里面,
|
|
然后遇到了文件夹的Permission issue,这个时候千万不要用sudo git clone ...
来尝试解决问题,而必须要改变当前文件夹的权限。
为什么呢?
因为如果用sudo来clone project,这个进程使用的ssh key是从 /root/.ssh里面来的,而不是/home/user/.ssh,换言之,你server所采用的public key和GitHub里面存的不是同一个,这么一来你就会看到从GitHub发来的Permission Denied error,然后陷入【为什么明明已经存了这个key它就是不认识??】的无限纠结(说的就是我)。
修改文件夹权限的指令是:
|
|
修改完成后,再次用git clone,这次是成功的(我的default key是有passphrase的,现在每次clone都要输一遍……不开心)。
当我尝试删除GitHub里面的id_rsa.pub文件,只保留github.pub文件时,我是无法进行git clone操作的(如图12)……太闹心了。
两个public key都在我的authorized_keys文件中,难道只能有一个是active的吗……
目前还没有发现解决方案,如果有朋友知道的话请告诉我一下😢…
References: