SSH 协议基础和 wireshark 数据包分析
内容简介:我们经常会使用我们也明白这是使用了SSH协议进行登陆,但我们想知道的是,为什么可以使用SSH协议进行登陆,而且为什么使用SSH就是安全的,其背后的原理是什么?下面我们就一起来探讨下这几个话题。
本文转载自:https://juejin.im/post/5baaf517e51d453df0442dce,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有。
一、SSH协议简介
我们经常会使用 ssh username@hostIp
命令登陆我们的 linux 服务器,如下图所示:
我们也明白这是使用了SSH协议进行登陆,但我们想知道的是,为什么可以使用SSH协议进行登陆,而且为什么使用SSH就是安全的,其背后的原理是什么?下面我们就一起来探讨下这几个话题。
当然啦!如果现在你手头上有相关公网可访问的云主机,那么请你登陆你的云主机,然后执行 grep sshd.*Failed /var/log/secure
命令看看,或许你会惊讶的发现有很多输出日志,你就会明白到底有多少人想尝试登陆你的主机了。
简单地说,SSH协议是建立在不安全的网络之上的进行远程安全登陆的协议。它是一个协议族,其中有三个子协议,分别是:
- 1、传输层协议
[SSH-TRANS]
:提供 服务器 验证、完整性和保密性功能,建立在传统的TCP/IP协议之上。 - 2、验证协议
[SSH-USERAUTH]
:向服务器验证客户端用户,有基于用户名密码和公钥两种验证方式,建立在传输层协议[SSH-TRANS]
之上。 - 3、连接协议
[SSH-CONNECT]
:将加密隧道复用为若干逻辑信道。它建立在验证协议之上。
二、SSH协议握手过程分析
在接着下面的内容之前,这里有几个概念非常重要!
- 1、
会话密钥 key
:key是通过客户端和服务器之间通过诸如D-H算法协商出来的。 - 2、
公钥 pub key
:pub key成为服务器主机密钥server_host_key
,用于SSH-TRANS
传输协议进行服务器验证,说白了就是客户端去验证服务器用的
SSH协议握手过程大致流程如下图所示:
下面是小编通过wireshire工具抓的数据包,让我们分别一步步进行分析:
- 1、TCP三次握手建立连接
我们都知道,TCP协议有个叫三次握手的过程,从上面图中可以看出序号(647-649)即是TCP连接建立过程。
NO. | 描述 | seq | Win | ACK | 解释 |
---|---|---|---|---|---|
647 | 第一次握手 | 0 | 8192 | 无 | seq = 0表示客户端当前的TCP包序列号 |
648 | 第二次握手 | 0 | 14600 | 1 | seq = 0,表示服务器端当前的TCP包序列号 ack = 1(客户端seq + 1),表示对客户端第 seq = 0 的TCP包进行应答 |
649 | 第三次握手 | 1 | 65536 | 1 | seq = 1,表示客户端端当前的TCP包序列号 ack = 1(服务器seq + 1),表示对服务器端第 seq = 0 的TCP包进行应答 |
- 2、SSH版本协议交换
上图序号(647-649)即是SSH版本协议交换过程。
NO. | 描述 | 解释 |
---|---|---|
650 | 协议版本协商 | 服务器将自己的SSH协议版本发送到客户端,格式为: SSH-protoversion(版本号)-softwareversion(自定义) SP(空格一个,可选) comments(注释,可选) CR(回车) LF(换行)
|
651 | 协议版本协商 | 客户端将自己的SSH协议版本发送到服务器,格式为: SSH-protoversion(版本号)-softwareversion(自定义) SP(空格一个,可选) comments(注释,可选) CR(回车符) LF(换行符)
|
这一步其实没什么高大上的内容,就是发送一个格式为 SSH-protoversion-softwareversion SP comments CR LF
的字节流而已。
- 3、密钥协商key
上图序号(652-677)即是SSH版本协议交换过程。
密钥协商过程从客户端和服务器相互发出 Key Exchange Init
请求开始,主要是告诉对方自己支持的相关加密算法列表、MAC算法列表等。
最后协商成功之后,将会生成一个对称加密 会话密钥key
以及一个 会话ID
,在这里要特别强调,这个是对称加密密钥key,不要和公钥相混淆了,公钥和密钥在上面开头已经着重强调两者的区别了,公钥是给客户端去验证服务器用的。
在这一步中,公钥会从服务器传送到客户端:
而会话密钥是通过D-H算法计算出来的,不会在网络上传输,其破解的难度取决于离散对数的破解难度,一般不会被破解的,有兴趣的可以自行了解该算法原理。
下面我将贴出 Key Exchange Init
发送的请求包数据分析
NO. | 描述 | 解释 |
---|---|---|
1 | kex_algorithms |
密钥交换算法,里边即包含我们使用的D-H算法,用于生成会话密钥 |
2 | server_host_key_algorithms |
服务器主机密钥算法,可以采用 ssh-rsa,ssh-dss,ecdsa-sha2-nistp256 ,有公钥和私钥的说法,公钥即我们上面讲到的pub key,对于公钥私钥的概念,可以参见 understanding public key private key concepts
|
3 | encryption_algorithms_client_to_server |
对称加密算法,常用的有 aes128-cbc,3des-cbc
|
4 | mac_algorithms_client_to_server |
MAC算法,主要用于保证数据完整性 |
5 | compression_algorithms_client_to_server |
压缩算法 |
- 4、认证阶段
上图序号(678-680)即是SSH版本认证阶段。
-
1、基于账号和口令的验证方式
客户端将自己的
用户名 + 密码
用上面生成的会话密钥key
进行加密之后传送到服务器端进行验证,服务器端验证通过,则响应成功,否则在进行有限次(推荐是20次)重新认证。至于服务器是怎么验证的,是否结合了会话ID小编也不清楚,网上众说纷纭。注意,用户名和密码是采用上面密钥协商阶段生成的会话密钥key进行加密的,包括后面的连接会话阶段所传送的数据都是,不要认为是采用服务器的pub key加密的
-
2、基于公钥和私钥的验证方式
这种方式也称为免密登陆。简单地说,就是客户端自己生成公钥私钥(通常采用ssh-keygen程序生成),然后将公钥以某种方式(通常是手动添加)保存到服务器
~/.ssh/authorized_keys
文件中,以后服务器都会接受客户端传过来的经过会话密钥加密过的公钥,然后解密得到公钥之后和本地authorized_keys
配置的公钥是否相等,如果是,则允许登陆。
如果你配过github或者gitlab的公钥,其实第二种方式认证方式很好理解,因为github它们也是采用SSH协议进行代码克隆的,没有配置公钥好像是不允许克隆的。
三、相关问题
- 1、密钥协商阶段安全吗?有没有中间人攻击的情况!
就我的理解,第一次总是不安全的。为什么呢?上面说到协商过程中,服务器会将自己的公钥 server_host_key_algorithms
发送给客户端,但是客户端无法保证它拿到的公钥就是目标服务器所发出来的,很可能有个中间人拦截了你的请求,然后中间人发了另外一个公钥给到你客户端,这就不安全了!这也很好解释了为什么我们第一次登陆的时候,Shell终端总是会出现这个提示的原因:
这也是将确认权留给客户端自己去判断的一种策略。相反,如果想要更加安全,那么我们可以采用第二种认证方式进行登陆。由于提示的是经过MD5之后的公钥,那么我们怎么判断这个值是有效的呢?请看下面第3个疑问。
- 2、传输协议协商出来的会话密钥和会话ID到底有什么作用?
会话密钥:对称加密算法的密钥,用于对通信数据进行加解密,会话ID有点像WEB中的Session,就是用来表示每一个会话的,同时在认证阶段也起判断是否同一会话有效的作用。
- 3、既然密码验证登陆,那么客户端第一次登陆的时候如何验证服务器公钥的正确性?
请你告诉小编吧!小编苦于找不到答案!
四、其他
下面是相关资料文档:
- 1、 SSH RFC中文文档地址
- 2、 The Secure Shell (SSH) Protocol Architecture
- 3、 The Secure Shell (SSH) Transport Layer Protocol
我们可能会问了,既然有了SSH协议文档,那么假如我们想要照着文档写一个实现出来,那么应该怎么去入手呢?其实SSH中的传输协议 [SSH-TARNS]
是基于TCP协议的,因此我们可以从创建一个最基本Java Socket套接字开始,逐步实现SSH的传输协议、认证协议以及连接协议。如果你对实现过程感兴趣,可以研究下 ganymed-ssh2-build209.jar
中的源码,结合SSH协议RFC文档,你就会发现,其实SSH协议中的协商和认证过程,其实都是通过Socket输入流、输出流的形式实现的。小编自己撸到协商阶段果断放弃,原因是不懂得算法太多了!
推荐阅读
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇 ### MySQL索引底层解析与优化实战 - 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少? - Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理 - Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开 - Zookeeper是个啥?特性和应用场景大公开 - ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节 - 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用 - Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位 - RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略 - 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南 - RocketMQ特性和应用场景揭示:理解其精髓与差异化优势 - Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析 - ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用 - MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学 - BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用 - Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析 - 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示 - 解密Netty粘包与拆包现象,怎样有效应对这一常见问题 - 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术 - Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处 - Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现 ----------------------- 七、结语与回顾
-
SSH 协议基础和 wireshark 数据包分析
-
SSH 协议分析和 wireshark 数据包分析
-
ssh工作流程及原理-SSH(Secure Shell Protocol,安全的壳程序协议),它可以通过数据包加密技术将等待传输的数据包加密后再传输到网络上。ssh协议本身提供两个服务器功能:一个是类似telnet的远程连接使用shell的服务器;另一个就是类似ftp服务的sftp-server,提供更安全的ftp服务。 连接加密技术简介 目前常见的网络数据包加密技术通常是通过“非对称密钥系统”来处理的。主要通过两把不一样的公钥与私钥来进行加密与解密的过程。 公钥(public key):提供给远程主机进行数据加密的行为,所有人都可获得你的公钥来将数据加密。 私钥(private key):远程主机使用你的公钥加密的数据,在本地端就能够使用私钥来进行解密。私钥只有自己拥有。 SSH工作过程:在整个通讯过程中,为实现SSH的安全连接,服务端与客户端要经历如下五个阶段: 版本号协商阶段 SSH目前包括SSH1和SSH2两个版本,双方通过版本协商确定使用的版本 密钥和算法协商阶段 SSH支持多种加密算法,双方根据本端和对端支持的算法,协商出最终使用的算法 认证阶段 SSH客户端向服务器端发起认证请求,服务器端对客户端进行认证 会话请求阶段 认证通过后,客户端向服务器端发送会话请求 交互会话阶段 会话请求通过后,服务器端和客户端进行信息的交互 一、版本协商阶段 服务器端打开端口22,等待客户端连接; 客户端向服务器端发起TCP初始连接请求,TCP连接建立后,服务器向客户端发送第一个报文,包括版本标志字符串,格式为“SSH-<主协议版本号>.<次协议版本号>.<软件版本号>”,协议版本号由主版本号和次版本号组成,软件版本号主要是为调试使用。 客户端收到报文后,解析该数据包,如果服务器的协议版本号比自己的低,且客户端能支持服务器端的低版本,就使用服务器端的低版本协议号,否则使用自己的协议版本号。 客户端回应服务器一个报文,包含了客户端决定使用的协议版本号。服务器比较客户端发来的版本号,决定是否能同客户端一起工作。如果协商成功,则进入密钥和算法协商阶段,否则服务器断开TCP连接。 说明:上述报文都是采用明文方式传输。 二、密钥和算法协商阶段 服务器端和客户端分别发送算法协商报文给对端,报文中包含自己支持的公钥算法列表、加密算法列表、MAC(Message Authentication Code,消息验证码)算法列表、压缩算法列表等等。 服务器端和客户端根据对端和本端支持的算法列表得出最终使用的算法。 服务器端和客户端利用DH交换(Diffie-Hellman Exchange)算法、主机密钥对等参数,生成会话密钥和会话ID。 由此,服务器端和客户端就取得了相同的会话密钥和会话ID。对于后续传输的数据,两端都会使用会话密钥进行加密和解密,保证了数据传送的安全。在认证阶段,两端会使用会话用于认证过程。 会话密钥的生成: 客户端需要使用适当的客户端程序来请求连接服务器,服务器将服务器的公钥发送给客户端。(服务器的公钥产生过程:服务器每次启动sshd服务时,该服务会主动去找/etc/ssh/ssh_host*文件,若系统刚装完,由于没有这些公钥文件,因此sshd会主动去计算出这些需要的公钥文件,同时也会计算出服务器自己所需要的私钥文件。) 服务器生成会话ID,并将会话ID发给客户端。 若客户端第一次连接到此服务器,则会将服务器的公钥数据记录到客户端的用户主目录内的~/.ssh/known_hosts。若是已经记录过该服务器的公钥数据,则客户端会去比对此次接收到的与之前的记录是否有差异。客户端生成会话密钥,并用服务器的公钥加密后,发送给服务器。 ****服务器用自己的私钥将收到的数据解密,获得会话密钥。 服务器和客户端都知道了会话密钥,以后的传输都将被会话密钥加密。 三、认证阶段 SSH提供两种认证方法: 基于口令的认证(password认证):客户端向服务器发出password认证请求,将用户名和密码加密后发送给服务器,服务器将该信息解密后得到用户名和密码的明文,与设备上保存的用户名和密码进行比较,并返回认证成功或失败消息。 基于密钥的认证(publickey认证):客户端产生一对公共密钥,将公钥保存到将要登录的服务器上的那个账号的家目录的.ssh/authorized_keys文件中。认证阶段:客户端首先将公钥传给服务器端。服务器端收到公钥后会与本地该账号家目录下的authorized_keys中的公钥进行对比,如果不相同,则认证失败;否则服务端生成一段随机字符串,并先后用客户端公钥和会话密钥对其加密,发送给客户端。客户端收到后将解密后的随机字符串用会话密钥发送给服务器。如果发回的字符串与服务器端之前生成的一样,则认证通过,否则,认证失败。 注:服务器端对客户端进行认证,如果认证失败,则向客户端发送认证失败消息,其中包含可以再次认证的方法列表。客户端从认证方法列表中选取一种认证方法再次进行认证,该过程反复进行。直到认证成功或者认证次数达到上限,服务器关闭连接为止。实例
-
SSH 协议基础和 wireshark 数据包分析
-
使用 WireShark 分析 SSH 协议
-
DevOps] 详细分析:SSH 协议工作原理、安全配置和实用技巧
-
SSH 协议的原理和用法:深入分析 SSH 协议的原理和用法
-
安全通信协议 SSH 的应用和分析
-
网络协议分析:Wireshark 可分析环路数据包,以确定故障并解决问题!