本文是《计算机网络》的自学课程,视频地址为:https://www.bilibili.com/video/av47486689。仅做个人学习使用,如有侵权,请联系删除


第五章:传输层

我们要学习的协议汇总:


要分清协议在哪些层

传输层两种协议的应用场景

TCP进行的是可靠传输(能确保数据完整性,数据丢失了就重传),UDP是不可靠传输

  • TCP传输有分段、编号和流量控制功能,需要建立和保持会话,例如QQ的文件传输就是TCP,ftp用到也是TCP,访问网站也是TCP

    netstat -n可以查看回话

  • UDP不编号,一个数据包完成,不建立会话(传输没有回复就重新发),例如QQ聊天用的就是UDP(从QQ聊天的一些特征可以判断出来,例如信息发送失败是过一会儿再提示、消息过长会分割成几条,因为超出了UDP中要求的单个数据包的最长大小了)

    UDP用于多播:1发送对多接收,可以防止由于某个终端的卡顿而导致的对整体的影响,这也能解释直播的时候丢包的原因:不可靠传输

传输层和应用层之间的关系

http=TCP+80端口

https=TCP+443端口

ftp=TCP+21端口

SMTP=TCP+25

POP3=TCP+110

RDP(远程桌面)=TCP+3389

共享文件夹=TCP+445

MySQL=TCP+3306

DNS=UDP+53 or TCP+53(少见)

其实就是传输层加了一个端口来给它一个名称而已

其他一些要记住的端口:

应用层协议和服务之间的关系

端口就是用来区分服务的,一台服务器可以同时运行很多服务,每个服务一直监听一个端口-》用IP地址定位计算机,用端口定位服务

查看计算机监听的端口:netstat -an

通过端口扫描工具,就可以知道某一台服务器在运行哪些服务,这种就可以用来攻击,所以为了安全,我们可以更改服务的默认端口,这样扫描工具就算扫描到也不知道是干什么的;或者可以混淆黑客认为我们在使用另一个服务、使用错误的方式攻击,使得攻击失败。

Windows防火墙

首先,先将没有用的端口都关掉

黑客一般先要在目标机器上装一个远程控制软件,然后才好控制

给一个直观化的展示:


入侵完成之后,还可以删除远程控制服务,一点痕迹都不留

使用防火墙可以关闭所有端口,也就是拦截所有流入的流量,当然这种就有点控制太严格了。但是可以是如果只提供WEB服务,只开启80端口就好了:


但是有了Windows防火墙并不能阻止所有的攻击,下面就介绍一个“灰鸽子木马程序”作为例子,防火墙对于木马程序是没有办法拦截的:

灰鸽子木马程序

木马程序是用户主动感染、感染后木马程序主动向外传输数据,所以防火墙对于这种向外的流量是不拦截的。

hhh这些文件必须加密压缩保存,否则容易被杀毒软件杀掉

  1. 配置灰鸽子,写入自己的ip,让感染的肉鸡主动来连接你

  2. 设置安装路径、程序图标、安装后自动删除安装文件等

  3. 生成应用程序,想办法让用户安装:这就教导了我们要去正规站点下载软件、不要安装来历不明的软件和不知名的小软件、要相信杀毒软件别人家都查杀出木马了你还不信,木马这种东西不破坏系统、不影响使用,真的是悄无声息的,中招了自己也不知道

  4. 中招的电脑会“自动上线”,根本不需要用户的账号密码,也没有迹象表明中招了:

  5. 可以实时控制电脑、查看文件


    (默默抱紧了我的linux)

  6. 其实也不是完全的无迹可寻,我们还是可以通过会话查木马:


    查看会话可知,有个8000端口

    也可以从服务中看出来:


    最后那个就是灰鸽子,注意它的“已停止”是假象,其实没停止

  7. 其实这个也可以有骚操作,比如用这个代替远程桌面帮忙解决电脑问题,对方在内网环境都没事(当然本机要有公网IP,否则鸽子都没办法找你报道),完事了运行一下杀毒软件把木马删除掉2333

    杀木马:拔网线运行杀毒软件23333

  • 如何解决?

控制输出的数据包,只有源端口是80的数据包才允许出

使用Windows网络层安全来严格控制流量:

  1. 新建安全策略

  2. 添加规则:拒绝所有ip通讯

  3. 添加规则:允许从本机80端口到任意端口和从80端口进入本机

  4. 此时不能主动访问任何设备,木马程序自然也就失效了:


    也可以对Ip而不是端口进行控制,比如要求只有特定的ip能访问本机

UDP协议


UDP不建立会话,较为节省服务器资源

UDP的报文格式


UDP没有序号,一个数据包搞定

UDP校验和:

TCP


流量控制:如果发送数据的速度大于接收数据的速度,接收不过来了,多余的数据包就只能扔掉了。接收端会告诉发送端减慢发送速度

避免网络拥塞。

TCP是全双工:例如A向B发送数据,B可以反馈是否正常接收了数据、是否发送过快、是否存在网络拥塞。

面向字节流的通信

以字节为单位进行传输

先将要传输的数据放到TCP缓存中,但向其中放数据是没有规律的,但是单个数据的大小是以字节为单位的。

从缓存中拿数据、组装数据包也和放入缓存时候的大小没关系,取几个字节也是不一定的。拿出数据后,加上头部进行传输。

接收端接受到后,去掉头部、放入缓存。从缓存读数据也不一定是一次几个字节。

套接字

每一条TCP通讯只能有两个点:发送端和接收端


套接字=IP地址+端口

可靠传输

网络是不可靠的:网络层遇事不决就丢包,可靠传输是由传输层实现的


如果不确认,等稍大于一个往返时间之后就超时重传,重发原来的数据包。


确认包丢失之后:丢弃重发的重复数据包、重传确认包

确认迟到:确认数据包迟到、比等待时间长时,会重传,对方再发来确认,这样发送端会收到两个确认数据包,但并不做什么、就是正常发下一个数据包


只要没有确认,就认为没到达,就重传

重传是自动进行的,不需要请求确认

信道利用率

TCP的缺点之一就是信道利用率太低


信道利用率=发送数据包所用时间/发送+确认整个过程的总时间

提高信道利用率:流水线传输


不再等待、一直发

  • 如何实现流水线传输的可靠传输?


发送窗口:窗口内的数据包可以连续发送,不需要等确认。只有在窗口中的数据包才能传输

每当前面的数据包确认了,窗口就向后移动,后面的数据包就能发送了。已经确认的数据包可以在缓存中清除

窗口中的数据包不能从缓存中清除,要时刻准备数据包没收到、需要重传

平均往返时间:这个会话平均花费的往返时间

不断调整、计算加权平均往返时间:


超时重传时间要大于等于加权平均往返时间

累积确认

再优化,可以使接受端使用累积确认:



B计算机回复收到第三个,就表示1-3都收到了,也就是一个间隔确认一次

如果有丢包情况发生怎么办?


例如3数据包丢失了,那么B会回复收到了2,之后的都需要重发。这也体现了累积确认的问题:不能体现单个数据包是否收到,会产生多余重复发送的问题

TCP首部


TCP数据部分在网络层就已经封装好了,传输层只加TCP首部到数据部分前面

一般首部都是20字节,也就是不加选项的,但是有些特殊情况,例如协商之类的,就比20字节长

序号:只记录发送的数据段的第一个字节是总的数据的第几个字节

确认号:

确认号是需要的下一个字节


第二个是确认,第三个和第四个是向客户端传输。好好看上面那个图

确认号是确认对方,序号看的是自己

数据偏移:记录TCP报文段第多少个字节之后就开始有数据了,也就是为了解决选项的长度不确定。数据偏移最大能表示15,但是它的一个1代表4个字节,所以最多能表示60个字节。而首部固定部分的长度是20字节,所以选项部分的长度最多也就是40字节

标记位:

URG:表明数据包的优先级,用于优先传送(加塞儿).如果标记为1,则优先传送

ACK:如果为0,则确认号无效

SYN:用于同步,syn=1表示建立会话的请求,此时ACK就是0,因为此时还没有建立请求、没有传送:


会话建立之后,syn就是0了


所以抓包时,看到SYN数据包就知道是用来发起会话的数据包

syn攻击:不断向服务器发起建立会话的请求,但是给出虚假的原地址,使得服务器一直处于等待会话建立的过程中、占用内存和CPU、影响其他用户正常使用。这个攻击在xp系统上很有效,但是2003已经修复这个漏洞了:


攻击开始,CPU立刻占用满:



抓到的数据包,都是SYN包:


还有一种更夸张,它建立会话的请求目标地址和源地址都是服务器自己,使得自己和自己建立大量会话:


PSH位:PSH标记为1的数据包会直接被放到目标机缓存的前面(加塞)

RET:取值为1时,表示TCP会话出现了严重问题(例如访问WEB时点取消),必须释放会话、重新建立连接(但不自动建立连接,只表示出现问题)

FIN:表示传输完成、释放会话

紧急指针:指明紧急数据的尾部,也就是说明紧急数据的范围

选项:通知服务器自己能接收的最大数据包的大小、是否支持选择型确认等选项。如果选项不够四个字节,就会填充以凑够四个字节

接收窗口确定发送窗口

客户端通知服务器端,告知自己的接收缓存,由此调整服务器端的发送缓存

服务器端通知客户端自己的接收缓存,由此调整客户端的发送缓存

抓包分析


第一步,访问DNS,然后DNS服务器返回网站的ip地址

第二步,客户端向服务器端建立会话,同时通知服务器本机最大能接受的数据包大小

第三步,服务器向客户端返回,通知服务器端最大接受数据包大小和窗口大小(就是我们上面讲的那个发送窗口)

第四步:客户端向服务器发送,说明本机最大缓存字节数


TCP首部中的数据:

拥塞控制

要求网络中所有的计算机,在发现丢包之后,要主动降低发包速度,避免网络彻底堵塞



理想的拥塞控制:链路能传输100M,但是传输到路由器的是150M,路由器丢掉50M,整个系统正常运行。只要大于100M都丢掉。这个是理想情况,是不考虑路由器实际处理能力的。

无拥塞控制:路由器同时要处理的数据包太多、越来越近乎于死机,使得处理量反而减小(拥塞-死锁)

拥塞控制:可以避免出现网络吞吐量下降甚至变成0的情况,但是丢包是不可避免的

慢开始



没有拥塞,就扩大窗口;出现拥塞,就减小一点


一开始以指数级别、每次二倍的速度增长,直到慢开始门限之后,变成+1增长。

出现堵塞(丢包)时:

  1. 重新计算慢开始门限,是出现堵塞时候的值的一半

  2. 重新开始慢开始。

    这就降低了发送速度以及发送速度增长的瓶颈(慢开始门限),从而使得网络比较不容易堵塞

快重传、快恢复

快重传和快恢复是在慢开始之后提出的另外一种实现拥塞控制的思路


接受法推测出发生丢包后立刻发出重复确认,连续发出三个重复的确认。

如果发送方收到了三个连续的确认:


和前面一样,调整慢开始门限。但是不再从慢开始开始,而是直接从快恢复开始,进行加法增加。

可以看出,这种恢复的速度比较快

发送窗口的实际上限值


发送窗口的上限取拥塞窗口和接收窗口的最小值

传输连接管理

TCP三次握手
  1. 客户端向服务器发送同步数据包,同步位SYN=1,确认号ACK=0,序号seq=x
  2. 服务器端收到后识别出来是建立连接的数据包,然后服务器端发数据包进行回应。SYN=1,ACK=1,seq=y,ack=x+1

其实有了上面两个数据包,足以证明网络是畅通的,也足以协商通信所需参数

  1. 客户端收到之后再给服务器发,ACK=1,seq=x+1,ack=y+1

如果没有第三次,会出现这样的问题:

如果客户端第一次由于网络不畅通等原因,数据包传输时间大于等待时间,则客户端会认为是丢包,然后再发一遍。但是服务器端先后收到这两个建立连接的请求后会认为是客户端再次发出的一个新的连接请求(TCP 协议是不限制一个特定的连接(两端 socket 一样)被重复使用的。),所以会开启两个会话,并给客户端返回两个数据包,但是客户端只认其中一个,因为它只申请了一个会话。所以有一个服务器端的会话就一直处于等待状态,浪费资源。

但其实这只是表象,知乎有答案探讨了这个问题:3次握手是对四次握手的简化

2与3都是 B 发送给 A,因此可以合并在一起,因此成为three way (or three message) handshake(其实翻译为三步握手,或者是三次通信握手更为准确)

三次握手(A three way handshake)是必须的, 因为 sequence numbers(序列号)没有绑定到整个网络的全局时钟(全部统一使用一个时钟,就可以确定这个包是不是延迟到的)以及 TCPs 可能有不同的机制来选择 ISN(初始序列号)。

接收方接收到第一个 SYN 时,没有办法知道这个 SYN 是是否延迟了很久了,除非他有办法记住在这条连接中,最后接收到的那个sequence numbers(然而这不总是可行的)。

这句话的意思是:一个 seq 过来了,跟现在记住的 seq 不一样,我怎么知道他是上条延迟的,还是上上条延迟的呢?

所以,接收方一定需要跟发送方确认 SYN。

假设不确认 SYN 中的 SEQ,那么就只有:

只有B确认了收到了 A 的 SEQ, A 无法确认收到 B 的。也就是说,只有 A 发送给 B 的包都是可靠的, 而 B 发送给 A 的则不是,所以这不是可靠的连接。这种情况如果只需要 A 发送给 B ,B 无需回应,则可以不做三次握手。

三次握手建立TCP连接的各个状态:


我们可以在计算机上查看各个会话的状态:


前面讲过的SYN攻击时,显示的会话是这个样子的:

TCP的连接释放



注意,客户端向服务器端发消息要求断开时,客户端不能继续向服务器端发送数据,但是服务器端依然可以接着发送、客户端也要接收,只有服务区端也发信息、通知客户端发送完成时,客户端才停止接收。然后客户端还需要发一个消息表示同意:



2MSL(2倍的最长报文寿命,默认是两分钟)。为了防止发给服务器端的同意结束的包丢失(如果丢失,服务器会重发,客户端需要能收到):


服务器的close-wait状态

01-01 12:38