2023年7月3日发(作者:)
SSH协议基本原理及wireshark抓包分析⼀、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协议做更加详细的介绍,我们可以⾃⾏百度⼀下。下⾯的写作思路将先通过wireshire抓包分析SSH协议上述三个流程,最后将提出整个学习过程中⼩编遇到的问题进⾏探讨。⼆、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.647648描述第⼀次握⼿第⼆次握⼿seq00Win819214600ACK⽆1解释seq = 0表⽰客户端当前的TCP包序列号seq = 0,表⽰服务器端当前的TCP包序列号ack = 1(客户端seq + 1),表⽰对客户端第 seq = 0 的TCP包进⾏应答seq = 1,表⽰客户端端当前的TCP包序列号ack = 1(服务器seq + 1),表⽰对服务器端第 seq = 0 的TCP包进⾏应答649第三次握⼿16553612、SSH版本协议交换上图序号(647-649)即是SSH版本协议交换过程。NO.描述协议版本协商解释650服务器将⾃⼰的SSH协议版本发送到客户端,格式为:SSH-protoversion(版本号)-softwareversion(⾃定义) SP(空格⼀个,可选)comments(注释,可选) CR(回车) LF(换⾏)651NO.协议版本描述协商客户端将⾃⼰的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.12描述kex_algorithmsserver_host_key_algorithmsencryption_algorithms_client_to_servermac_algorithms_client_to_servercompression_algorithms_client_to_server解释密钥交换算法,⾥边即包含我们使⽤的D-H算法,⽤于⽣成会话密钥服务器主机密钥算法,可以采⽤
ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,有公钥和私钥的说法,公钥即我们上⾯讲到的pub key,对于公钥私钥的概念,可以参见对称加密算法,常⽤的有aes128-cbc,3des-cbc34MAC算法,主要⽤于保证数据完整性5压缩算法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、2、3、我们可能会问了,既然有了SSH协议⽂档,那么假如我们想要照着⽂档写⼀个实现出来,那么应该怎么去⼊⼿呢?其实SSH中的传输协议[SSH-TARNS]是基于TCP协议的,因此我们可以从创建⼀个最基本Java Socket套接字开始,逐步实现SSH的传输协议、认证协议以及连接协议。如果你对实现过程感兴趣,可以研究下中的源码,结合SSH协议RFC⽂档,你就会发现,其实SSH协议中的协商和认证过程,其实都是通过Socket输⼊流、输出流的形式实现的。⼩编⾃⼰撸到协商阶段果断放弃,原因是不懂得算法太多了!
发布者:admin,转转请注明出处:http://www.yc00.com/web/1688339782a123085.html
评论列表(0条)