SSH协议概述
SSH全称是Secure Shell protocol,即安全外壳协议,是一种在不安全网络上提供安全远程登录及其它安全网络服务的协议。OpenSSH是SSH协议的免费开源实现,提供了服务端后台程序和客户端工具,用来加密远程控件和文件传输过程中的数据,并由此来代替不安全的传统远程登录协议(例如Telnet)和文件传输协议(例如FTP),有效地解决了传统协议中的安全性问题。
SSH实现安全连接过程
1. 建立TCP连接
-
客户端与服务器通过TCP三次握手建立TCP连接。
2. SSH 协议版本协商阶段
-
SSH 目前包括 SSH1 和 SSH2 两个大版本。
-
服务器通过建立好的TCP连接向客户端发送一个包含 SSH 版本信息的报文,格式为 “SSH-<SSH 协议大版本号 >.<SSH 协议小版本号 >-< 软件版本号 >”,软件版本号主要用于调试。
-
客户端收到版本号信息后,如果服务器使用的协议版本号低于自己的,但是客户端能够兼容这个低版本的 SSH 协议,就使用这个版本进行通信。否则,客户端会使用自己的版本号。
-
客户端将自己决定使用的版本号发给服务器,服务器判断客户端使用的版本号自己是否支持,从而决定是否能够继续完成 SSH 连接。
-
如果协商成功,则进入密钥和算法协商阶段。
3. 密钥和算法协商阶段
-
SSH 支持多种加密算法,双方根据自己和对端支持的算法进行协商,最终决定要使用的算法。
-
服务器端和客户端分别发送算法协商报文给对端,报文中包含自己支持的以下算法列表:
-
公钥算法列表(密钥交换算法)
-
密钥交换算法通常采用Diffie-Hellman 算法,用于生成会话密钥和会话 ID。
-
-
加密算法列表(对称加密算法)
-
在生成会话密钥和会话 ID之后,SSH的后续数据传输都将采用对称加密算法来加密整个连接过程。
-
客户端将使用会话密钥,结合对称加密算法,对传输到服务器端的数据进行加密。服务器端将使用同样的会话密钥,结合对称加密算法,对客户端发来的密文进行解密。
-
同理,服务器端将使用会话密钥,结合对称加密算法,对传输到客户端的数据进行加密。客户端将使用同样的会话密钥,结合对称加密算法,对服务器端发来的密文进行解密。
-
-
MAC算法列表(消息验证码)
-
MAC生成算法用的是哈希算法。
-
会话密钥加密后的每条消息都会附加上MAC作为消息的一部分,以便于另一方可以用它验证数据包的完整性,即数据包是否在传输过程中被篡改过。
-
MAC根据会话密钥,消息的分组序列号和实际信息组成的内容算出来的。
-
MAC通常作为数据包的最后部分发送到对称加密区域之外。
-
SSH数据传输过程通常会先用会话密钥加密数据,然后计算MAC。
-
-
压缩算法列表
-
SSH传输的数据是经过压缩的,保证了传输的速度。
-
-
-
服务器端和客户端根据自己和对端支持的算法来决定最终要使用的各个算法。
-
服务器端和客户端利用 Diffie-Hellman 密钥交换算法,主机密钥对等参数,生成会话密钥和会话 ID。会话密钥用于在后续的通信过程中两端对传输的数据进行加密和解密,而会话 ID 用于认证过程。
-
DH密钥交换算法生成会话密钥的大致过程:
-
服务器收到客户端的DH请求后,将P(一个大素数),G(大于1的整数)发给客户端。
-
客户端利用非对称加密算法生成客户端私钥a,并利用P,G,a生成客户端公钥e,并将e发给服务器。其中e生成算法如下:
-
服务器收到客户端公钥e后,利用非对称加密算法生成服务器私钥b,并利用P,G,b生成服务器公钥f,并将f发给客户端。其中f生成算法如下:
-
服务器利用自己的私钥b,客户端公钥e,以及大素数P,即可生成会话密钥K。其中K的生成算法如下:
-
客户端收到服务器公钥f后,利用f,客户端私钥a,大素数P,即可生成会话密钥K。其中K的生成算法如下:
-
由此,客户端与服务器可以在仅传输P,G,对端公钥的情况下,结合本端私钥,生成相同的会话密钥,会话密钥并没有在网络上进行传输,保证了会话密钥的安全性。
-
-
会话ID由客户端服务器初始报文、客户端服务器SSH_MSG_KEX_INIT 的有效载荷、主机密钥、客户端服务器DH公钥、会话密钥等因子,共同计算生成。
-
4. 认证阶段
-
从这个阶段开始的所有消息都经过会话密钥加密传送
-
客户端向服务器发送认证请求,认证方式有两种:
-
password认证
-
客户端向服务器发出 password认证请求,将用户名和密码用会话密钥加密后发送给服务器;服务器用相同的会话密钥将该信息解密后得到用户名和密码的明文,与设备上保存的用户名和密码进行比较,并返回认证成功或失败的消息。
-
-
publickey 认证
-
采用数字签名的方法来认证客户端。
-
客户端向服务器发送登录 IP 和用户名,服务器识别对应的客户端公钥(保存在 authorized_keys 中),找到该公钥后,服务器通过公钥加密一段随机字符串,再用会话密钥加密后发给客户端。
-
客户端首先使用会话密钥解密密文,再使用自己的私钥解密得到原始的随机字符串。然后用自己的私钥加密随机字符串,在用会话密钥加密后发给服务器。
-
服务器用会话密钥解密,再用客户端公钥解密,拿到随机字符串,则说明客户端的私钥与保存在服务器的公钥对应,客户端身份认证成功,否则认证失败。
-
-
5. 会话请求阶段
-
服务器等待客户端的请求。
-
客户端身份认证通过后,会向服务器发送会话请求。
-
服务器处理客户端的请求。请求被成功处理后, 服务器会向客户端回应 SSH_SMSG_SUCCESS包,SSH进入交互会话阶段;否则回应 SSH_SMSG_FAILURE包,表示服务器处理请求失败或者不能识别请求。
6. 交互会话阶段
-
客户端将要执行的命令用会话密钥加密后传给服务器。
-
服务器接收到报文,用会话密钥解密后执行该命令,将执行的结果用会话密钥加密发还给客户端。
-
客户端将接收到的结果用会话密钥解密后显示到终端上。