SSH协议浅析

什么是SSH

Secure Shell(缩写为SSH),由IETF的网络工作小组(Network Working Group)所制定;SSH为一项创建在应用层和传输层基础上的安全协议,为计算机上的Shell(壳层)提供安全的传输和使用环境。最早的时候,互联网通信都是明文通信,一旦被截获,内容就暴露无疑。1995年,芬兰学者Tatu Ylonen设计了SSH协议,将登录信息全部加密,成为互联网安全的一个基本解决方案,迅速在全世界获得推广,目前已经成为Linux系统的标准配置。我们用的比较多的GitHub就用到了SSH来进行身份认证,方便我们上传代码。

基本用法

1
$ ssh user@host
1
$ ssh -p 2222 user@host//修改端口号,默认是22

SSH加密原理

  1. 首先客户端发起连接请求,远程主机返回客户端自己的公钥。
  2. 客户端使用公钥加密密码,发起登录请求。
  3. 服务端使用私钥对请求进行解密,密码正确后登录成功。

关于公钥加密,这里简单说下,公钥加密又称为非对称加密,这种加密方式下有一对密钥:公钥和私钥,公钥加密后的密文只能由私钥解密,私钥加密后的密文只能由公钥解密。公钥是可以公开的,私钥必须秘密保存。这就带来了巨大的优势:由公钥加密的内容只能由持有私钥的人解密;由私钥加密的内容别人无法伪造。这里SSH的加密用到了第一点优势。

这里存在着一个漏洞,如果客户端的连接请求被中间人截取,中间人返回客户端自己的公钥,这时候客户端的密码就有暴露的风险。那么SSH是如何解决这个问题的呢?
答案很简单,公钥的真实性由用户自己来确定。首次连接远程主机时,会有如下的提示:

1
2
3
The authenticity of host 'host (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?

大致意思是,无法验证远程主机的真实性,但是我可以告诉你这个主机的公钥指纹,你自己去核实吧。那么去哪核实呢?一般来说远程主机会在自己的网站上贴出公钥指纹的,方便用户核实。核实后就可以进行连接了。

SSH的公钥登录

有人可能会有疑问了,不对啊,我往GitHub的仓库里提交代码时也不会让我输入密码啊,只需要第一次时配置一个id_rsa.pub就好了啊。这就是SSH提供的第二种登录方式了:公钥登录。

所谓”公钥登录”,原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。这里其实是公钥加密的第二个优势的应用:用户的私钥加密的内容任何人都无法伪造,加密后的内容只能用公钥解密,篡改后就不能被解密。

生成公钥和私钥:

1
$ ssh-keygen

运行结束以后,在$HOME/.ssh/目录下,会新生成两个文件:id_rsa.pub和id_rsa,前者是你的公钥,后者是你的私钥。然后上传到主机:

1
$ ssh-copy-id user@host

如果用的是GitHub需要自己复制id_rsa.pub的内容到网站中。