网络协议学习总结
身不饥寒,天未尝负我;学无长进,我何以对天。
导航
壹-链路层
1、ARP 协议
-
简介:链路层之间的通讯只需关注双方(任意网段的双方均可而非限定同一网段内的双方)的 MAC 地址即可无需 IP 信息,但网络的设计(跨网段通信由网关转发数据包)使得主机只需要关注同一网段内主机的 MAC 即可,无需关注其它网段内主机的 MAC 信息。【为了链路层与网络层之间能关联起来,设计终端 IP-MAC 的映射关系。如果每次通过 ARP 请求的方式来获取映射关系效率较慢,便设计 ARP 高速缓冲表以供快速查询映射关系,查询不到再通过 ARP 请求。】【由于 ARP 是二层协议,因此接收者并不会区分网段,所以同 VLAN 下 2 网段的主机可以发送 ARP 询问 3 网段主机的 MAC 信息(实测可行)。但二层报文一律不能够跨越三层路由进而进行转发。】
-
ARP 表项学习触发时机:(1)自己不知道向别人询问时,根据别人的回答对自己的 arp 表项进行学习维护(发送请求并收到响应时,学习响应 arp 中的源 ip-mac);(2)别人不知道向自己询问时,回答并根据别人的提问内容学习维护自己的 arp 表项(接收请求且 target ip 匹配自己的 ip 时,则响应请求并学习请求 arp 中的源 ip-mac);(3)一个陌生人发来询问或回答时,不予理睬(收到请求但 target ip 不匹配自己的 ip 时,arp 包直接被丢弃不进行 arp 源 ip-mac 学习)。【华为交换机严格 ARP 学习只有符合(1)中的触发时机时才会学习 ARP 表项】
-
动态 ARP 老化参数:老化超时时间、老化探测次数。(设备上动态 ARP 表项到达老化超时时间后,设备会发送老化探测报文(即 ARP 请求报文),如果能收到 ARP 应答报文,则更新该动态 ARP 表项,本次老化探测结束;如果超过设置的老化探测次数后仍没有收到 ARP 应答报文,则删除该动态 ARP 表项,本次老化探测结束。)【老化探测时的 ARP 请求报文二层的目的 MAC 地址是单播而非常规 ARP 请求中的广播地址。】
-
ARP 种类:普通 ARP、免费 ARP、翻转 ARP(RARP-老版 DHCP)、逆向 ARP(IARP)、代理 ARP(类似于 ARP 欺骗,需要交换机设备支持)。
-
正常 ARP、免费 ARP、IP 探测 ARP 的区别:三者所使用的数据包格式基本上是相同的,区别在于(1)免费 ARP 中所询问的目标 IP 地址是它自身,而正常 ARP 中所询问的目标 IP 地址是同网段的其它 IP 主机。(2)免费 ARP 的目的是为了在自己的 IP-MAC 对应关系发生变化的时候及时通知其它主机更新其 ARP 缓冲中已保留的旧的 IP-MAC 对应关系。(3)IP 探测 ARP 报文的 target ip 是自己,sender mac 是 0。该报文的目的是为了在初次使用 ip 时首先探测网络中是否存在同样的 ip,若此时收到响应则电脑会弹出 ip 冲突的提示。
(ARP 消息中 Sender 和 Target 的设置均根据当前场景下已知信息进行维护),见下图

貳-网络层
1、IP 报文
-
分片过程:(1)将大数据包分成符合最大传输的小数据包(2)将各小数据包分别添加对应的 IP 包头(3)各包头中会发生变动的字段 Total Length、Identification、Flags、offset,其中 Identification 总是相等的。(主机每发送一个包标识值加 1,而同一包被分片之后的各包的标识值却是相等的)注意如下:
-
TCP 传递下来的包通常不需要进行分片,因为在 TCP 处的 MSS 就已经保障了封装的包大小不会超过传输上限;而 UDP 传递下来的包则可能会发生 IP 包分片的效果,如超大的 ICMP 负载报文就可以看到分片效果。(ICMP 回应包将携带 ICMP 请求包所负载的数据,如 abcd...)
-
超大 ICMP 包分片 wireshar 分析中发现:分成 4 个分片的 IP 包,只有最后一个在 wireshark 中显示的是 ICMP 协议,前 3 个包都是 IP()/data,实际上只有第一个包里边的 data 才携带了 ICMP 包头的消息,剩下的都是数据。至于为什么 wireshark 最后一个包显示 ICMP 包头是因为 wireshark 对所有的包进行了重组之后统一将 ICMP 包头消息添加显示在了最后一个包上面。(个人觉得这样容易误导使用者,建议在第一个分包处进行 ICMP 包头信息的显示)
-
分片过程发生在网络层,因为网络层收到上面发下来的包由其直接分片然后进行包头封装这个过程会很便利。而如果这个过程交给链路层来做的话,那么链路层分包后还需要将各 IP 包头所对应的字段进行修改,这个过程对于链路层来说会较为麻烦。
-
TTL(Time to Live)存活时间:限制数据包在网络中被路由转发的最大次数,通常也相当于数据包经过的路由器数量。【但在二层网络中传输时该值的大小并不会发生变化,因为此过程中只是发生了二层 MAC 转发并没有发生三层 IP 转发即路由转发】
-
Identification 标识:主机每发出一个 IP 包,该值将加 1。此字段存在的意义仅在 IP 分片的时候才有作用,其它时候并无太大意义。【它同 ICMP 报文中的 Identifier 字段的意义是不一样的】
2、ICMP 协议
-
ICMP 报文通用格式中的 Type+Code 字段的每种组合均代表一个 ICMP 类别,而每种类别的 ICMP 报文格式又都有自己的特点。例如,ICMP Echo 回显类别中的 Identifier 字段的作用是为了一 一对应请求包/响应包;ICMP 目的不可达类别中会携带未送达报文的 IP 头+部分负载数据。
-
常用报文类别:Echo 回显(ping)、目的不可达、重定向、超时、参数异常、源端关闭。其中除了 Echo 回显以外,其余几乎均会携带 问题报文的 IP 头+8/64 字节上层协议的部分数据(实测不止 64 字节),部分消息还会额外携带一个对应消息类型的关键字段,如重定向字段 Gateway Internet Address、参数问题字段 Pointer。
-
重定向:在特定的情况下,当路由器检测到一台机器使用非优化路由的时候,它会向该主机发送一个 ICMP 重定向报文,请求主机改变路由。如,当路由器从某个接口收到数据还需要从相同接口转发该数据时;当路由器从某个接口到发往远程网络的数据时发现源 ip 地址与下一跳属于同一网段时。
-
超时:即在报文转发过程中 TTL 存活时间变为零时,网络设备会向包的发起者发送 ICMP 超时报文。
-
参数异常:报文字段的值有错误。
-
源端关闭:用于表示对方或中途的服务器繁忙无法回应时,网络设备发送 ICMP 源端被关闭消息给该目的主机。如,当网络设备没有足够的缓存空间存储到某个目的主机的报文时,这些报文会被该设备丢弃;当到达某一个主机的数据包过快来不及被主机处理,则该主机也可以发送 ICMP 源端被关闭消息以便降低数据包速率。

叁-传输层
1、TCP 三次连接和四次挥手

总结:
-
三次握手阶段确立的事情:双发初次发包时携带的 seq 号即 ISN(在 wireshark 中显示的相对号均为 1,实际值并非 1)、初次的窗口大小、窗口因子、MSS 每个包最大大小。
-
三次握手与四次挥手都是基于一问一必答互相各问一次的机制,只不过握手 2 阶段是挥手 2、3 阶段的整合而已。
-
而为什么客户端问完服务器(1 问答),服务器又问一次客户端呢(2 问答)?这是为了检验客户端是否确实是要进行连接或是断开的操作,而不是客户端随意或是不经意的一次操作。(因为这种操作对于客户端来说影响不大,但是对于服务器来说,这种行为是要进行内存划分与回收的操作的,很容易造成内存不足服务器卡死,传输数据失败等问题)
-
为什么挥手 2 阶段发生之后需要等待一段时间之后才会发起 3 阶段的报文?因为 1 阶段仅仅说明客户端的发送窗口没有数据可发,但是他的接收窗口还在和服务器的发送窗口进行着传输。而当服务器的数据发送完成之后,服务器才会进行 3 阶段的报文,进行最终的关闭操作。【注意观察 4 次挥手图片中 2 次数据传输中的箭头】
-
为何 4 阶段发生之后,客户端需要等待 2MSL 的时长之后才进行关闭操作?假如客户端发完 4 阶段的包之后就进行关闭操作,那么当 4 号包丢失之后,服务器就会进行重传操作,但是客户端的连接已经关闭对应的缓冲区也已释放,故这个包并不会得到客户端的回复,于是在经历数次重传失败之后,服务器只能依托 keep-active 来进行关闭操作,故可知整个过程会使得服务器的缓冲区长时间不能被回收。 而在等待 2MSL 的时长里,如果真有服务器的重传包那么肯定已经过来了,此时再进行回复之后客户端再次开启 2MSL 的计时等待。如果没包过来,默认服务器已经收到并已关闭连接,那么客户端也就开始关闭连接;而实际上,服务器可能就是因为网络极差或是突然断网的原因导致没有收到包或是重传包没过来,导致要进行上述的 keep-alive 包的过程。因此 4 次挥手的完整过程也只是在网络条件理想的情况下进行交互的过程,故理想状态下服务器的关闭要比客户端要早。 当然若真的有一种方案可以解决极差网络下的握手挥手问题,我觉得这又回到了两军对阵的问题上。(任何网络协议的过程都是以网络情况理想为前提的,当然也会有一种网络理想之外的万能的解决办法,即 keep-active 保活检测。)
2、TCP 滑动窗口
-
当 TCP 堆 栈接收到数据的时候,生成一个确认信息并以回复的方式发送,但是放置在接收端缓存中的数据并不总是立即被处理。当服务器忙于处理从多个客户端接收的报文, 服务器很有可能因为清理缓存而变得缓慢,无法腾出空间接收新的数据,如果没有流控,则可能会造成丢包和数据损坏。好在,接收窗口所设定的速率无法使服务器 正常处理数据时,能够调整接收窗口大小。通过减小返回给发送端的 ACK 报文的 TCP 头窗口大小值来实现。
-
服务端发送零窗口,当客户端接收到此报文时,它会暂停所有数据传输,但会保持与服务器的连接以传输探测(keep-alive)报文。探测报文在客户端以稳定间隙发送,以查看服务器接收窗口状态。一旦服务器能够再次处理数据,将会返回非零值窗口大小,传输会恢复。
-
滑动窗口直接与服务器无法接收和处理报文有关,任何窗口大小的缩小以及零值都是服务器问题的直接结果。

(猜测:接收/发送窗口和接收/发送缓冲区大小不一致,窗口值显示的是当前缓冲区的可用大小。)
3、包重传机制
-
延迟重传:发送方发出包后,经过 RTO(通过多个包往返时间计算出来的一个平均时间,RTO 是包重传延时计时器的计量单位)之后依旧没有收到来自接收方的 ACK 确认包,就会触发重传。这种重传接收端并不清楚发生了什么事。
-
快速重传:发送方发出 1、2、3 个包,而接收方收到 1、3 个包,此时接收方因为没有收到预期顺序的包而触发重复 ACK,当接收端收到几个同样的重复 ACK 包之后,就会触发发送方的重传。此时将暂停其它数据包的发送直到重传包被再次发送出去才解除暂停,这种重传由接收端参与并触发。【重复 ACK 是指在接收方收到乱序报文时,所发出的一类 TCP 报文。TCP 使用报文头的序列号和确认号以有效保证数据按照发送的顺序接收和重组。】
-
为什么是收到 3 个重复 ACK 确认包时才会触发快速重传?快速重传是为了重传丢失的包而不是乱序的包,而乱序包通常混乱的距离不会太远,因此为了避免乱序包误触发快速重传,规定当收到 3 个同一个包的 ACK 确认包时才触发快速重传。
-
快速重传又分为:普通重传和 SACK 重传。如,发送 1-10 个包,其中只有 3、6、9 号包丢失,那么(1)普通重传:接收方将 3 号包的 3 个重复 ACK 发给发送方,发送方会将从 3 号包开始的 8 个包再次依照 PSH_ACK 和 ACK 的常规数据传输交互方式进行重传(2)SACK 重传:接收方会将 3 个 SACK 的包发给发送方(每个 SACK 包中将记录自己这边已经收到的包),此时发送方对丢包情况了如指掌,此时就只需要将缺少的 3、6、9 号包依次发送即可。

(数据包第一次重传的延时等待是一个 RTO,随后每次重传的延时等待将会随指数增长。Win 的重传上限是 5 次,Linux 是 15 次。若达到一定次数还没有成功时则本地放弃并发送一个复位信号。)
4、TCP 中 Flag 标志的含义
- PSH 标志:让接收方尽快将缓存区中的内容交付给接收应用进程,而不再等待整个缓存区都填满了后再向上交付。(如,一个较大的 http 响应报文被拆分成 3 个 tcp 包进行传输,那么这 3 个 tcp 中的前 2 个的 flag 都是 ack,只有第 3 个才是 psh+ack;若一个的 http 请求报文较小,那么这个报文仅由一个 tcp 包进行传输即可,此时它的 flag 就是 psh+ack。由此可知,psh 标识也意味着一个阶段的完成。猜测:wireshark 应该就是根据 tcp 的 psh 来分析哪些 tcp 包可以被重组为一个完成的 http 报文。)
5、网络慢速高延时分析
主要观察包与上一个包之间的相对时间。(1)若 TCP 三次握手过程中收到的 SYN/ACK 报文的时间较长,则应该是线路延迟(因为 3 次握手过程所花费的时间很短,不会存在客户端延迟问题);(2)若应用层发出应用请求包的时间较长,则应该是客户端延迟(因为客户端发起的应用层请求通常在握手完成之后立马就会发出,不应该会等待);(3)若收到的应用层响应包响应时间较长,则在排除线路延迟的情况下那么就应该是服务器延迟(通常是由于服务端压力过大导致请求处理繁忙或服务端程序设计存在问题)。

6、杂项
-
TCP 建立连接之时(即三次握手阶段),双方会互相协商 MSS 的值(此值仅表明发送报文时该分段的最大字节值)、以及各自的最大窗口值(窗口值可能会不同,取决于各自的 TCP 情况)。之后在互相传输数据的过程中,发送方会根据网络的拥塞情况而动态的调整其传输的数据,但其值总不会超过接收方的接受窗口的值。
-
客户端与服务器各自维护一个 TCP 缓冲池,当他们各自向对方发送应用层包时,其 Seq 号是以各自缓冲池的情况顺序进行的。通常情况下,各自的 TCP 确认包的 Seq 号是维持在各自 Next Seq 的值上,它的存在并不会改变应用包的 Seq 序列号的顺序。
-
在用 Socket 编程时,UDP 协议要求包小于 64K。TCP 没有限定,TCP 包头中就没有“包长度”字段,而完全依靠 IP 层去处理分帧。这就是为什么 TCP 常常被称作一种“流协议”的原因,开发者在使用 TCP 服务的时候,不必去关心数据包的大小,只需将 SOCKET 看作一条数据流的入口,往里面放数据就是了,TCP 协议本身会进行拥塞/流量控制。(不过鉴于 Internet(非局域网)上的标准 MTU 值为 576 字节,所以建议在进行 Internet 的 UDP 编程时,最好将 UDP 的数据长度控制在 548 字节 (576-8-20)以内。)
-
当客户端收到来自服务器的包,但是在收到之后的近 100 毫秒内客户端没有发往服务器的包,则客户端会专门发送一个 TCP 的确认包。通常在收到包之后的近 100 毫秒内客户端有发往服务器的应用包,则客户端的 ACK 确认数据就包含在应用包中发给了服务器。
-
TCP 存活包 keepalive 探测:存活时长(7200 秒)、探测间隔(75 秒)、存活重试次数(9 次)【值可手动更改】。TCP 协议自带的该特性基本没用,故默认处于关闭状态。一般见到的 Keepalived 包应该都是应用层程序触发实现的。
肆-应用层
1、DHCP 协议(UDP)【同类型协议 BOOTP(UDP),但已被 DHCP 取代】
-
DHCP 客户端与服务端进行通信时,客户端发包使用的源端口总是 68(bootpc),服务端总是 67(bootps)。
-
DHCP 应用层的报文类型只分两种:客户端请求、服务端回应。报文格式总是分为两部分:通用格式、Option 格式。其中 option 格式的起始 option id 总是 53(代表 DHCP 消息类型),结尾 option id 总是 255(代表 option 结束字段)。
-
报文通用格式中的 Transaction ID 用来标识客户端与服务端在发起会话过程中的所传输的包(如 discover 四过程中的包的 id 都是相同的。renew 两过程中包的 id 是相同的)。
-
报文通用格式中四个 IP 地址的区别:Client IP address【表示客户端在发包之前的地址。在 discovery 阶段,客户端还未拥有 ip 故为 0.0.0.0;在 renew/release 阶段,客户端已拥有 ip 故为当前 ip 地址。】、Your (client) IP address【表示服务器分配的地址。在 discovery/renew 阶段,由服务端发往的 offer/ack 报文中会被设置。】、Next server IP address【表示 DHCP 服务器的地址,告知客户端向这个服务器进行 ip 信息的请求。在 discovery/renew 阶段,由服务端发往的 offer/ack 报文中会被设置。】、Relay agent IP address【表示 DHCP 中继地址。只有当 DHCP 报文经过中继设备时,才会由 DHCP 中继进行该字段值的设置,否则默认为 0.0.0.0。】(DHCP 服务器会根据此中继地址来选择对应网段的 DHCP 池,从而进行 ip 信息的分配。)
-
IP 租约相关。在 offer/ack 报文中会携带:租约总时长、续租时间点(在总时长的 50%时发起续租请求)、重绑定时间点(若续租失败,则在总时长的 87.5%时重新开始 discovery 四过程阶段)。
-
若 DHCP 客户端与服务端此前已有交互,那么在客户端与服务端处双方各自会留存一份 ip 使用记录(不管上次是否通过 release 释放)。这样当客户端下次再次发起 ip 请求时(不管是续租请求还是发现请求),客户端会主动再其 option 字段中使用 Option: (50) Requested IP Address 来再次使用之前的 ip 地址;或者客户端本地已无此记录但是服务器还存在,那么服务器应该还会为此客户端分配此 ip 地址。
-
discovery 四过程中,客户端 2 次发出包的目的 mac 总是 ff、源 ip 总是 0.0.0.0、目的 ip 总是 255.255.255.255,服务端 2 次发出包的目的 mac 和目的 ip 总是客户端实际的 mac 和由服务器分配给它但未使用的 ip 地址。【猜测:服务端发出的目的 ip 似乎并无意义,主要还是通过目的 mac 通过二层传输将包转送给目的客户端。而无 ip 的客户端在收到这个带目的 ip 的报文之后会特殊允许通过,然后客户端才能拥有 ip。费解:客户端没有 ip 但却可以通过 UDP 的应用层进行通信?】
2、DNS 协议(UDP/TCP)
-
DNS 服务支持 UDP 和 TCP,监听于 53 号端口。DNS 客户端域名查询时通过 UDP 进行数据传输,当 DNS 主备服务器进行区域传送时通过 TCP 进行数据传输。【通过 dig +tcp www.baidu.com 可以强制 DNS 查询使用 TCP 进行数据传输】
-
DNS 通用报文中 Questions【请求查询的域名数量】、Answer RRs【响应回答的数量】、Authority RRs【权威记录数量】、Additional RRs【附加记录数量】,这些值标明了可选报文部分的大致结构。其中权威记录和附加记录通常在查询域名服务类似 baidu.com 时,其中的块才会出现权威块列出了查询到的 NS 记录,附加块将这些 NS 记录进行了 A 解析。(dig baidu.com 这条命令第一次使用时才会出现权威附加记录,否则得等 DNS 缓冲记录老化之后再次使用才能出现)(猜测:是否可以通过一个查询报文查询多条域名记录,此时 Questions 就不再是常见的 1 了)
-
通用报文 Flag 字段中 RD(Recursion Desired)和 RA(Recursion Available)分别表示:客户端期望的查询方式、服务端实际所使用的查询方式。【递归/迭代】
-
响应包中可选报文中 Queries 和 Answers 块中 Name 字段的字节大小需要注意。Queries 中的 name 字段是将实际域名通过编码为 label 序列后的值,这些值的开头会记录这个域名被编码的长度;而 Answers 中 name 字段代表的应该是对应 Queries 中的 name 值的一个索引,实际并不存储域名本身的值(这也就是为什么响应回答报文中会包含查询请求报文中的内容)。
-
域名查询时机:本机的 dns 缓冲池--> 本机 hosts 表--> 向配置的所有 dns 服务器发出请求
-
DNS 查询分为两种:递归查询和迭代查询。递归查询:发出 DNS 请求后,要求对方查好后直接给出最终结果。迭代查询:发出 DNS 请求后,对方如果不知道这个域名的 IP 是什么,会告诉我有可能知道这件事的机器的 IP,我自己再去问有可能知道的机器,不断重复直到问到结果。

3、HTTP 协议(TCP)
-
应用层 HTTP 的报文字段同应用层的其它协议有所不同(如 DNS、DHCP 等),它传递给传输层作为 Payload 中的数据格式是:key: value,[key: value],而其它协议则通常都是:value,[value]。【而在 wireshark 中看到的效果却和其它应用层协议无区别,这是由于 wireshark 针对性解析的原因。】
-
TCP 连接断开与 HTTP 请求响应的关系:在 HTTP/1.0 中,客户端建立一个 tcp 连接并发送 http 请求,当 http 响应被服务端发送并确保客户端已 ack 的情况下,服务端则主动开始 tcp 四次挥手进行 tcp 断开操作;(这样每次请求都需要建立新的 tcp 连接代价较大)在 HTTP/1.1(该版本最流行)中,支持持久连接并默认开启字段 Connection,这样在完成一个 http 请求之后建立的 tcp 连接通道并不会马上断开,短时间(打开一个包含很多的 js、css、图片等文件的页面,那么这些文件就会被浏览器立马请求通过这条已建立的 tcp 通道进行数据传输;而如果页面已加载完成这时候等了几秒中之后又去访问页面上的一个资源时,这时候就可能会建立新的 tcp 通道了)内可以被重复使用。
-
HTTP/2 多路传输:一个 TCP 连接中可以依次发送多个 HTTP 请求,依次收到多个 HTTP 响应,而非一问一答。但在 HTTP/1.1 中默认则是通过一问一答的方式,支持 Pipelining 但效果不佳。
-
浏览器对同一 Host 建立 TCP 连接的数量限制。当一个页面中包含了 1000 张图片要去获取/请求,(1)如果是 HTTP/1.0 的方式,则需要建立 1000 个 tcp 连接;(2)如果是 HTTP/1.1 的方式,则建立一个 tcp 连接然后顺序下载速度较慢也不妥,所以 Chrome 浏览器(其余浏览器各有所区别)允许对同一个 Host 最多建立 6 条 TCP 连接。如果 6 条通道都被使用那么其它请求就需要等待了;(3)如果是 HTTP/2 的方式,则应该会使用多 TCP 通道及多路传输。(但是现实中 HTTP/2 都是在 HTTPS 上实现的,因此对于 HTTP 的页面多资源请求就只能使用 HTTP/1.1)
4、SSL/TLS 协议(TCP)
-
通道建立流程:(1)Client Hello(2)Server Hello、Certificate、Server Key Exchange、ServerHello Done(3)Client Key Exchange、Change Cipher Spec、Finish(Encrypted)(4)New Session Ticket、Change Cipher Spec、Finish(Encrypted)(5)通道建立完成,开始消息加密传输。【此处双方只交互了 4 次便完成了通道的建立,实际中交互次数并不确定,可能是 4 次也可能是将步骤二拆开变成 5 次。但总体上而言,其过程就是:“Hello 阶段协商加密套件,Key Exchange 阶段交换加密套件所需要的基础参数,Finish 阶段结束通道建立交互”。Certificate 内容的作用:身份认证、RSA 密钥交换】
-
TLS 历史版本:SSL 主要由网景公司设计并维护,SSL3.0 之后该公司停止维护,随后便主要由 IETF 将 SSL3.0 标准化为 TLS1.0,并持续维护了 TLS1.1、TLS1.2、TLS1.3 这些版本。
-
解密 TLS 数据包的方式有 2 种:(1)密钥交换算法选择 RSA,然后提取服务器的私钥,将私钥导入 Wireshark,通过 Wireshark 解密密钥交换过程中传递的预主密钥,再结合之前的客户端和服务器随机数生成主密钥,进一步生成加密密钥,即可解密后续抓取到的加密报文。(2)直接从客户端提取预主密钥,结合客户端和服务器随机数生成加密密钥,实现对加密报文的解密。【这两种方式的目的都是为了获取预主密钥,而该密钥的获取取决于 TLS 协商阶段选择的密钥交换算法是 RSA 还是 DH。实际上通常都是 DH 也就是使用第二种方法 wireshark 才能成功解密数据。】
-
TLS 协议构成:由记录协议和握手协议叠加而成。低层的记录协议负责确定上层的握手协议数据的封装格式,其格式总是固定的 类型、版本、长度、握手协议数据;上层的握手协议则负责加密通道协商及其它应用层数据的加密操作,其格式多种多样,不同的握手协议格式基本大不相同。【由于记录协议具有固定格式的特性,故通常一个 TLS 数据包中可以支持携带多个握手协议的数据。】


5、SSH 协议(TCP)
-
SSH 协议基本框架:传输协议(第一阶段明文通信。提供了服务器认证、数据加密、数据压缩功能。)、用户认证协议(第二阶段密文通信。向服务器提供了客户端用户鉴别功能。)、连接协议(第三阶段密文通信。提供了用途广泛的各种通道,如,安全交互式会话外壳、隧道技术转发专有 TCP/IP 端口和 X11 连接。)。【wireshark 只能看到第一阶段传输的数据包详情,关于 SSH 解密数据包解析目前 wireshark 暂不支持,目前只能通过重新改写 sshd 源码的方式更近一步了解其通信过程】
-
传输协议部分第一阶段通信建立流程:(1)Client:Protocol(2)Server:Protocol(3)Client:Key Exchange Init(4)Server:Key Exchange Init(5)Client:EC DH Key Exchange Init(6)Server:EC DH Key Exchange Reply,New Keys(7)Client:New Keys(8)传输层协议完成,开始后续交互【此部分同 TLS 通道建立的过程很相似,总体上也是:“打招呼、交换加密套件、根据确定的加密套件交换所需的基础参数、结束”,该过程主要是确定了对称会话密钥,以加密后续传输的认证、数据报文。步骤 6 中携带的服务端公钥的作用:身份认证、RSA 密钥交换】
-
身份验证方式:密码(Password)、公钥私钥(Publickey)、交互式(keyboard-interactive)。其中密码和公钥私钥登录的方式通过 SSH 协议框架第二阶段的用户认证协议进行验证,交互式登录则属于过 SSH 协议框架第三阶段的连接协议进行验证(具体情况不明)。【猜测:密码认证时,客户端使用传输层阶段得到的服务器公钥对要验证的账户及密码进行加密,然后发送给服务端由其使用私钥解密验证;公私钥认证时才会用到客户端公私钥对,客户端用私钥加密一段信息然后发给服务端,服务端用得到的客户端公钥进行解密由此验证了客户端可信任。】


6、FTP 协议(TCP)
-
FTP 工作原理:在两台通信的主机之间建立两条信息流,一条是控制流,用于传送控制信息(命令和响应),另一条是数据流,用于数据传送;其中控制流总是由客户端的随机端口向服务端的 TCP/21 号端口发起的连接,而数据流在 FTP 主动模式 PORT 下时,是由服务端的 TCP/20 号端口向客户端协商的随机端口发起的连接,在 FTP 被动模式 PASV 下时,是由客户端的随机端口向服务端协商的随机端口发起的连接。【被动模式是为了解决在主动模式下服务端无法与 NAT 后面的客户端建立连接而被设计】
-
数据流的两种传输方式:文本传输方式、二进制传输方式。当使用文本方式传输文件时,ftp 服务端通常会自动地调整文件的内容以便于把文件解释成适合另外那台计算机存储文本文件的格式;当使用二进制方式传输文件时,文件的内容都是原封不动一个字节都没有被改变过。因此,对于文本文件的传输,使用文本传输方式可以免去 windows 和 linux 回车符转换的问题,而对于非文本文件的传输,则最好使用二进制传输方式,否则可能会造成文件的传输错误。建议统一使用二进制方式进行传输,这样可以避免很多问题。
-
FTP 应用行为分析:首先建立一条控制流 TCP 连接(来自服务端的欢迎消息、登录认证交互、系统型号特性应答)。当客户端发送 PWD、CWD、PORT、PASV 等控制指令时,不会产生数据流通道的建立;当客户端发送 LIST 控制指令请求目录列表时,会触发数据流通道的建立,目录列表传输之后数据流通道由服务端主动发起 4 次挥手关闭;当客户端需要进行文件下载时,会重新建立一条控制流然后发送 RETR 下载指令,触发新的数据流通道建立,当文件下载完成之后这条新建的控制流和数据流通道将会被关闭(此行为来自对 FileZilla 客户端下载文件的观察,但实际上还是遵循控制流发送下载指令数据流传输文件的规则)。
-
报文类型分为两类:请求(Request cmd: Request arg)、响应(Response code: Response arg)。其中请求的 cmd 是 4 字节响应的 code 是 3 字节,cmd/code 与 arg 之间由 16 进制 20 分割,结尾是 16 进制的 0d0a 收尾。
(主动/被动 模式下的 请求/响应 报文中会携带待连接主机的 ip-port 信息),见下图

7、Kerberos 协议(TCP)
-
Kerberos 协议是一个专注于验证通信双方身份的网络认证协议,不同于其他网络安全协议的保证整个通信过程的传输安全,kerberos 侧重于通信前双方身份的认定工作,帮助客户端和服务端在一个不安全的网络中完成一次安全的身份认证继而进行安全的通信。
-
关键点:该协议借助“可信赖的第三方”来达到客户端和服务端双方身份鉴别的工作(通信中需要加密的部分数据均是使用对称加密实现,另一种双方身份互相鉴别的方式是通过客户端和服务端相互验证对方的公钥证书实现),“可信赖的第三方”别称 KDC 密钥分发中心 = AS 认证服务器+TGS 票据授权服务器+密钥数据库(一般是 AD 活动目录)。其中密钥数据库中存储着每个网络实体(AD 中的网络实体是指登录用户账户、机器账户,机器账户即加域的计算机名后面加一个 $符,如DC01$,机器账户的初始密码是由 120 个随机字符组成。)独有的密钥,这个密钥只有网络实体自己和 KDC 知道,这个密钥被用来对称加密网络实体与 KDC 之间的会话内容,而网络实体之间的会话内容则通过由 KDC 临时随机分配的会话密钥进行对称加密。详见
-
工作原理 简述:(1)用户输入账户和密码到客户端程序,客户端将密码通过单向函数进行哈希转化为“用户密钥”。(2)客户端向 AS 认证服务器发起 AS-REQ 请求【请求中包含用户登录账户等信息,若 KDC 启用了预身份认证则此处也会包含“用户密码”的信息】(3)AS 认证服务器给客户端返回 AS-REP 响应【响应中包含通过“TGS 密钥(即 KDC 内置的 Krbtgt 用户)”加密的“客户端-TGS 会话密钥”即 TGT 金票据、通过“用户密钥”加密的 “客户端-TGS 会话密钥”】(4)客户端向 TGS 票据授权服务器发起 TGS-REQ 请求【请求中包含通过“TGS 密钥”加密的 TGT 票据、通过“客户端-TGS 会话密钥”加密的时间戳】(5)TGS 票据授权服务器给客户端返回 TGS-REP 响应【响应中包含 通过“客户端-TGS 会话密钥”加密的“客户端-服务器会话密钥”、通过“服务器密钥(即机器账户的密钥)”加密的“客户端-服务器会话密钥”即 SS 银票据】(6)客户端向提供 service server 发起认证请求(该请求通常被夹带在应用服务通过 kerberos 认证的认证请求当中,不同于上面的 AS-REQ/TGS-REQ 这种单独的请求)【请求中包含通过“服务器密钥(即机器账户的密钥)”加密的“客户端-服务器会话密钥”、通过“客户端-服务器会话密钥”加密的时间戳】(7)service server 解密得到“客户端-服务器会话密钥”然后交互返回认证响应以完成认证,最终客户端正常连接应用服务。举例说明:抓包分析 SMB 登录时发现,先是通过 SMB 报文协商交互,然后开始进行 kerberos 交互客户端得到 TGT 金票据和 SS 银票据,然后继续开始 SMB 交互,此时会看到 SMB-Session Setup Request 报文中会包含 SS 银票据相关的信息,最后 SMB 交互完毕。
-
常见的网络服务认证均是基于密码进行的认证交互,而 Kerberos 则是是基于票据。总结以上认证流程无非就是:客户端首先向 KDC-AS 发起请求获得 TGT 金票据,然后客户端又拿着 TGT 票据向 KDC-TGS 申请 SS 银票据,最后客户端拿着 SS 票据向 service server 进行认证获得服务的访问权。因此,如果我们获得了 Krbtgt 用户的 HTML 密钥,就可以伪造 TGT 金票据;如果获得了机器账户的密钥,就可以伪造 SS 银票据。【使用一张 TGT 金票据可以申请到好多 SS 银票据,继而获得对各应用服务的访问权限。】
-
使用 Windows 域时,所有凭据都存储在 DC 域控制器中,每当用户尝试使用域凭据对服务进行身份验证时,服务都将请求 DC 域控制器来验证该用户身份是否正确。此时可以使用两种协议在 Windows 域中进行网络身份认证:(1)Kerberos: 任一最新版本的 Windows 都能使用,这是任意最新域中的默认协议。(2)NetNTLM: 为兼容性目的而保留的 遗留身份验证协议。
NetNTLM 网络认证,见下图

Kerberos 网络认证,见下图

Kerberos 流程数据包,见下图

8、NetBIOS 协议(API)
-
netbios 是一种会话层服务,而不是网络协议,属于一种应用层程序接口。它旨在让处在同一局域网下的不同计算机上运行的不同程序可以共处于同一个会话环境中,进而使得程序之间可以随意的传递数据信息。不同程序在进行网络上信息资源的获取和传输时只需调用 NETBIOS 提供的接口即可,而不必让程序员去深入理解各种网络套接字函数的用法之后才能进行工作,这为程序员提供了很大的便利。【NetBIOS 上层接口对相关网络信息的可用与否实际上和底层相关的服务是否正常运行有关,当服务承载在 TCP/IP 上时,底层则运行着 名称解析服务、数据报服务、会话服务 这三个服务以随时为上层提供服务。】
-
NetBIOS 会话层接口服务可以运行在 tcp/ip ipx/spx netbios frame(非路由网络协议,类似于一种帧协议)这些网络传输通讯协议之上,现代操作系统通常运行在 tcp/ip 的网络传输协议之上。运行在 TCP/IP 网络上时,相应的三个服务使用的端口分别为 UDP137(名称解析服务:主要作用是在局域网中提供计算机的名称或 IP 地址查询服务)、UDP138(无连接的数据报服务:主要作用是提供 NetBIOS 环境下的计算机名浏览功能)、TCP139/445(有连接的会话服务:用于处理 NBT 会话,NBT 会话用于包含 SMB 会话的轻量级协议,其主要作用是提供文件和打印机共享功能【139 端口似乎已被 445 端口替换,实测共享打印机和共享文件的数据包交互都是使用 TCP445 端口的 SMB 协议。】)。
-
NETBIOS 是可路由的服务,只是在默认情况下只在同一网段下的终端才广播注册互相发现对方。如果要实现不同网段的主机名服务,一般需要设置 WINS 来解析。【但通过 nbtscan x.x.x.x 实测发现,当不在同一网段时,依旧可以指定查询指定 ip 地址的 NBS 名称。】
NetBIOS 网络架构图,见下图

NetBIOS 名称服务/数据报服务 数据包,见下图

9、SMB/CIFS 协议(TCP)
-
SMB/CIFS 属于一种应用层的网络协议,主要功能是使网络上的机器能够共享计算机文件、打印机、串行端口和通讯等资源。SMB 可以以不同方式运行在会话层或者更低的网络层之上:(1)运行于 NetBIOS 之上(而 NetBIOS 本身则运行在 NetBEUI、IPX/SPX 或 TCP/IP 协议上)(2)直接运行在 TCP445 端口
-
工作原理:(1)版本协商【版本主要分为 SMB1、SMB2、SMB3,版本 1-2 使用较多】(2)认证协商【认证方式主要支持 NetNTLM、Kerberos】(3)认证交互(4)资源访问【文件读写类似于编程一样,需要经过 文件连接、信息获取、权限判断等繁琐的操作,而每一个操作又对应着数个网络请求包的发起/响应,过程相当繁琐。】
-
应用范围:(1)Windows 下 SMB/CIFS 是适用于 Windows 服务器和客端的标准文件和打印机共享系统,故 Windows 系统无需额外安装软件来;(2)Linux 下通过 Samba 软件服务来将 Linux 文件系统作为 CIFS/SMB 网络文件进行共享, 同时也支持将 Linux 下的打印机作为 CIFS/SMB 打印机共享而进行共享。
-
杂项:(1)文件共享通用连接方式\\ip,但在局域网内,由于 NBTBIOS 名称解析服务的存在,故也可使用\\MachineName 的连接方式。(2)SMB 共享对文件的操作与使用 FileZilla FTP 客户端对文件的操作过程很相似,都是在初次登录打开时产生一次 tcp 连接(连接包括协商、登录等过程),当点击进入一个目录时又会产生一次 tcp 连接(连接依旧包括协商、登录等过程)。
文件共享初次连接打开时所产生的包交互过程,见下图

10、RPC 协议
- rpc 协议作用于传输层之上应用层之下,使用的固定端口是 tcp135,动态端口 50000 以上,专门为程序网络接口调用所使用,相当于一个轻量版的 http 接口。
伍-杂项
-
技巧:对于各种应用层协议在 OSI 七层中的对应位置,通过 wireshark-统计-协议分级,可以帮助更好的理解。
-
技巧:当分析一个包含多个 TCP 会话的应用流程时,可以通过过滤器先筛选出 syn 相关的包(tcp.flags == 0x002)以确定会话数量(统计-会话-TCP 亦可查看),然后依次为不同的会话着不同的颜色,这样就会使得应用行为的先后顺序非常明显。
-
每一个捕获包的 Frame 层并非实际存在,它只是由 wireshark 捕获并添加,物理链路上实际传输的只是 Ethernet II 层的数据。(Frame 层主要记录了数据包被捕获的时间、包大小、以及包的序号这些信息。)
-
常用文件的文件头(十六进制):JPEG (jpg) 文件头:FFD8FF、PNG (png) 文件头:89504E47、GIF (gif) 文件头:47494638、XML (xml) 文件头:3C3F786D6C、HTML (html) 文件头:68746D6C3E、Adobe Acrobat (pdf) 文件头:255044462D312E、ZIP Archive (zip) 文件头:504B0304、RAR Archive (rar) 文件头:52617221。【文本文件无文件头直接开始就是数据】
-
以太帧 Ethernet Ⅱ 通过 Type 字段(IP、ARP 等)、IP 报文通过 Protocol 字段(TCP、UDP、ICMP、OSPF 等) 指出它们所携带的上层数据使用了何种协议,以便目的主机知道该将数据部分交给哪个进程进行处理。【猜测:TCP/UDP 报文可能也想过使用应用层类型字段的说法,但由于应用层软件太过丰富硬性规定灵活度不高,于是便将这个应用层类型字段以 Port 的方式替代。】