ssh的发展历程与基本原理

一、ssh是什么

SSH(Secure Shell)是一个提供数据通信安全、远程登录、远程指令执行等功能的安全网络协议,最初提出目的是替代非安全的Telnet、rsh、rexec等远程Shell协议。之后SSH发展了两个大版本SSH-1SSH-2

 

二、ssh的发展历史

1. 1.x版本

1995年,芬兰赫尔辛基理工大学的研究员Tatu Ylönen设计了ssh协议的第一个版本(现称SSH-1),目标是取代早期的rlogin, TELNET, ftp和rsh这些不安全的协议。同年七月,他以免费软件的形式发布了这个协议的一个实现,并迅速流行起来。

1995年12月,Ylonen创建了SSH Communications Security来发展和商业化SSH,SSH软件的原始版本使用了各种免费软件,如Gun libgmp,但是后来由SSH Communications Security发布的版本逐渐演化为私有软件。

2. 2.x版本

“Secsh”,IETF工作小组的官方互联网工程任务组,负责SSH协议的第二版本。在2006年,他们发布了SSH协议修订版,即SSH-2,并被采纳为标准。该版本与SSH-1不兼容,但在安全性和特性方面都优于SSH-1。更好的安全性,例如,通过Diffie-Hellman密钥交换和通过信息认证码进行强大的完整性检查。SSH-2的新特性,增加了在单个SSH连接上运行任意数量的shell会话的能力。由于SSH-2比SSH-1更有优势而且受欢迎,一些实现如Lsh和Dropbear仅支持SSH-2协议。

3. 1.99版本

在2006年1月,在2.1版本建立之后,RFC 4253指定一个支持ssh2.0以及兼容之前版本的SSH服务的协议版本为1.99。这不是一个实际的版本,而是一种识别向后兼容性的方法。

4. OpenSSH and OSSH

早在1999年,很多开发人员都很想要一个可用的免费版本,他们找到了SSH源程序的1.2.12发布版本,这是它在开放源码许可下发布的最后一个版本,Bjorn Gronvall的OSSH就是后来以这个为基础发展出来的。不久,OpenBSD开发人员在Gronvall的代码的基础上开了一个分支,并对其进行了大量的工作后,创建了OpenSSH,这是由2.6版本的OpenBSD发布的。在这个版本中,一个“可移植性”分支被创建了,目的是让OpenSSH能在其他操作系统中使用。

到了2005年,OpenSSH已经是最流行的SSH实现了,没有之一,在很多操作系统中都默认安装OpenSSH。与此同时,OSSH却过时了。OpenSSH一直在维护并支持SSH-2协议,在7.6版本的OpenSSH代码库中,去除了对SSH-1的支持。

 

三、ssh的主要特性

1. 加密

避免数据内容泄漏

2. 通信的完整性

避免数据被篡改,以及发送或接受地址伪装(检查数据是否被篡改,数据是否来自发送者而非攻击者) SSH-2 通过 MD5 和 SHA-1 实现该功能,SSH-1 使用 CRC-32

3. 认证

识别数据发送者和接收者身份 客户端验证SSH服务端的身份:防止攻击者仿冒SSH服务端身份,避免中间人攻击和重定向请求的攻击;OpenSSH 通过在 know-hosts 中存储主机名和 host key 对服务端身份进行认证 服务端验证请求者身份:提供安全性较弱的用户密码方式,和安全性更强的 per-user public-key signatures;此外SSH还支持与第三方安全服务系统的集成,如 Kerberos等

4. 授权

用户访问控制

5. 转发

可以通过SSH为Telnet、FTP等提供通信安全保障,支持三种类型的转发操作:Port Forwarding,X Forwarding,Agent Forwarding

 

四、ssh基本框架

SSH协议框架中最主要的部分是三个协议:

  • 传输层协议(The Transport Layer Protocol)提供服务器认证,数据机密性,信息完整性 等的支持;
  • 用户认证协议(The User Authentication Protocol) 则为服务器提供客户端的身份鉴别;
  • 连接协议(The Connection Protocol) 将加密的信息隧道复用成若干个逻辑通道,提供给更高层的应用协议使用; 各种高层应用协议可以相对地独立于SSH基本体系之外,并依靠这个基本框架,通过连接协议使用SSH的安全机制。
     
    同时SSH协议框架中还为许多高层的网络安全应用协议提供扩展的支持。它们之间的层次关系可以用如下图来表示:

SSH_layer

 

五、ssh的加密

1. ssh加密方式

SSH从安全和性能两方面综合考虑,结合使用了 Public Key/Private key(公钥/私钥) 和 Secret Key(密钥)。

  • Public Key/Private key:非对称加密,安全,但效率低,不适合大规模进行数据的加密和解密操作
  • Secret Key:对称机密,高效,但安全性相对较低,Key的分发尤其不方便

对密码学基础知识和数字签名了解,可以参考阮一峰的博文

2. ssh中的key

名称 生命周期 创建 类型 描述
Host Key 持久化 服务端

Public Key

Host Key是服务器用来证明自己身份的一个永久性的非对称密钥
User Key 持久化 用户 Public Key User Key 是客户端用来证明用户身份的一个永久性的非对称密钥(一个用户可以有多个密钥/身份标识)
Server Key 默认为1小时 服务端 Public Key Server Key 是SSH-1协议中使用的一个临时的非对称密钥,每隔一定的间隔(默认是一个小时)都会在服务器重新生成。用于对Session Key进行加密(仅SSH-1协议有,SSH-2对其进行了增强,这里Server Key作为一个概念便于在流程中进行描述)
Session Key 客户端 会话(Session) Secret Key Session Key是一个随机生成的对称密钥,用户SSH客户端和服务器之间的通信进行加密,会话结束时,被销毁

ssh框架图:

11111

 

六、安全连接的建立过程

SSH处理过程可以分解成几个主要阶段:

  • 协议协商阶段
  • 服务端认证阶段
  • 客户端认证阶段
  • 数据传输阶段

每个阶段均涉及到客户端与服务端的多次交互,通过这些交互过程完成包括证书传输、算法协商、通道加密等过程。

1. 协议协商阶段

1)服务端打开服务端口(默认为22),等待客户端连接

2)客户端发起TCP连接请求,服务端接收到该请求后,向客户端发送包括SSH协议版本信息

3)客户端接根据该版本信息与自己的版本,决定将要使用的SSH版本,并向服务端发送选用的SSH版本信息

4)服务端检查是否支持客户端的决定使用的SSH版本

至此,双方完成协议协商。如果该过程中,客户端或服务端发送SSH版本无法兼容,任何一方都可以断开连接。

2. 服务端认证阶段

完成协议协商阶段后,客户端与服务端已经建立明文的通信通道,之后进入服务端认证阶段。

SSH协议中没有明确的服务端认证过程,而通过一系列的服务端与客户端的交互来确定服务端的身份,该过程还会完成Host Key、User Key、Session Key等在客户端与服务端之间的传输。

1)建立连接后,服务端向客户端发送:

  • Host Key:用于认证服务端的身份
  • Server Key:用于帮助建立安全的数据传输通道
  • 8字节的随机数,即检测字节(check bytes):客户端通过在下一次响应中包含该随机数,防止IP地址欺诈
  • 服务端支持的加密算法、压缩方式和认证方式

这个时候,客户端和服务端使用Host Key、Server Key和检测字节生成一个128位的MD5值,作为此次会话的session id

2)客户端在接收到服务端Host Key后,会检查自己的knows host数据库中(一般为~/.ssh/know_hosts文件),是否已经包含当前服务端的Host Key,如果有则继续下一步;如果没有或包含当前服务端的其他Host Key,则由用户决定是否信任该服务端,或终止当前连接。

The authenticity of host 'ssh-server.example.com (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)?

如果客户端拒绝接受这个主机密钥,那么连接就中止了。否则,继续。

3)客户端向服务端发送session Key

出于性能考虑,SSH采用对称加密(Secret Key),对实际通信内容进行加密,即Session Key。因此Session Key的安全尤为重要,一旦Session Key泄漏给攻击者,那所有的通信数据都可能被攻击者截获。由于当前通道还是采用明文方式,客户端采用Host Key和Server Key对Session Key进行两次加密来加强安全性,同时还会发送检测字节和所选定的算法(这些算法是从第1步中服务器支持的算法列表中挑选出来的)。

4)服务端得到Session Key后,客户端和服务端就可以通过Session Key对数据进行加密解密操作,到此,双方完成安全(加密)通道的建立。 Host Key和Server Key都是Public Key(非对称加密),只有通过服务端的私钥(Private Key)才能对其解密,以得到Session Key。在正式使用安全通道前,客户端要求服务端发送使用Session Key加密的确认信息,以验证服务端的身份。 为避免Session Key的泄漏,SSH还采取了其他安全措施,Session Key仅保存在内存避免其泄漏;周期性更换Server Key,默认为1小时(SSH 2对Server Key安全进一步增强)。

3. 客户端认证阶段

SSH提供多种客户端认证方式。

SSH-1:

  • Password
  • Public Key
  • Kerberos
  • Rhosts && RhostsRSA
  • TIS

SSH-2:

  • Password
  • Public Key
  • hostbased 在SSH-2中考虑Rhosts存在安全漏洞,废弃了这种方式。

这里之讨论我们经常使用的的Password和Public Key方式。

此时安全通道已经及建立,之后的所有内容都通过Session Key加密后进行传输。

1)Password

Password 方式既客户端提供用户和密码,服务端对用户和密码进行匹配,完成认证。类Unix系统中,如 OpenSSH 的框架,一般通过系统的本地接口完成认证。

Password 的优势是简单,无需任何而外的配置就可以使用。缺点密码不便于记忆,过于简单的密码容易被暴力破解。

2)Public Key

Public Key认证的基本原理是基于非对称加密方式,分别在服务端对一段数据通过公钥进行加密,如果客户端能够证明其可以使用私钥对这段数据进行解密,则可以说明客户端的身份。因为服务端需要使用客户端生成的密钥对的公钥对数据首先加密,所以需要先将公钥存储到服务端的密钥库(Auhtorized Key)。还记得Github中使用git协议push代码前需要先添加SSH KEY吗?

下面详细介绍一个通过Public Key进行客户端认证的过程。

1) 客户端发起一个Public Key的认证请求,并发送RSA Key的模数作为标识符。(如果想深入了解RSA Key详细 --> 维基百科

2)服务端检查是否存在请求帐号的公钥(Linux中存储在~/.ssh/authorized_keys文件中),以及其拥有的访问权限。如果没有则断开连接

3)服务端使用对应的公钥对一个随机的256位的字符串进行加密,并发送给客户端

4)客户端使用私钥对字符串进行解密,并将其结合session id生成一个MD5值发送给服务端。 结合session id的目的是为了避免攻击者采用重放攻击(replay attack)。

5)服务端采用同样的方式生成MD5值与客户端返回的MD5值进行比较,完成对客户端的认证。

4. 数据传输阶段

该阶段通过Session Key提供的对称加密(Secret Key)算法,保证需要传输的任何数据的安全。

 

整体过程如下:

20140113163143937

 

七、参考

1. ssh(安全外壳协议)

2. Secure Shell

3. 《The Secure Shell: The Definitive Guide》

4. SSH 详解

5. SSH原理简介

6. SSH协议介绍

(完)

posted @ 2018-03-22 22:24  大师兄啊哈  阅读(3561)  评论(0编辑  收藏  举报