计算机网络(二)
主要讨论问题
其实我们上面一篇文章说过了,计算网络是结构化分层实现的。分层是因为利用抽象或者说面向对象的方法减少实现的复杂度。主流的TCP/IP protocol stack其实就是学习各个层具体实现的协议,当然在学习这些协议之前建立一个完整的立体观念很重要。这里我们再贴一张图,是来自OSI模型的
这张图着重看下面的1,2,3层,我们注意到这三层实际上是不在一般的pc或者server上实现的,而是在subnet的硬件(也就是router路由,switch交换机)上实现,但是这无关紧要,因为下层只需要向上层提供primitive operation(原语操作)就行了,通常这些原语操作是操作系统的syscall。在Linux系统中最为典型的就是应用层调用transport 层的原语进行通讯,常见的分别是:socket, accept, connect, bind, listen, send, recv。这些就是套接字通讯,套接字相当于连接了应用层和运输层。
我们来详细讲一下最低的两层:物理层和数据链路层(btw,我觉得数据链路层翻译得真的很好,在这一层中我们解决的就是数据帧frame如何从一条链路的一端传到另外一端,记住这是链路的端到端)
那么我们以一个最常见的ping命令来描述下链路层和物理层实现的是什么,解决了什么问题。
首先ping命令是基于ICMP协议,形成了一个IP数据报文(datagram),然后这个报文通过数据链路层和物理层提供的service传输到指定的host,如果能够到达,就会返回ICMP echo的回复报文,如果没有到达,就会显示time out。
Ethernet 以太网
首先我们先清楚一个LANs是什么,它是Local Area Networks的缩写,意思就是一定数量的终端,通过wired或者wireless的方式连接到同一台交换设备(switch)。在LANs中最为出名和运用最为广泛的就是Ethernet规范,它包括802.2(cable)和802.11(wireless)协议。传统的Ethernet是简单的将多台pc连接到同一条线路中,自然就需要处理Collison问题。通常通过三种方法;复分法,token传递法,随机接入法来解决。后来的switch改变了传统的接入方法,现在是LANs的每台主机都通过独自的频道连接到switch(wire或者wireless),当然此时switch就需要运用缓存来处理向外发的数据帧(因为LANs的所有主机如果想向外发报文,都只能通过switch的出口,如果多个同时向外发,那么switch就需要缓存来处理这些报文。当然这里也涉及到flooding问题)。
Ethernet Frame
MAC地址(有很多其他叫法),是数据链路层的独特地址,在数据链路层,数据帧的传递只能通过MAC地址来寻址。MAC地址不是分层的,不像IP地址一样有网络号和主机号。它一共有6个字节,前三个字节表明了生产厂商(厂商向IEEE象征性的付费购买),后3个字节则是厂商自己分配。当收到上层传来的IP datagram时,数据链路层通过ARP table找目标的IP地址对应的MAC地址,然后构建数据帧frame,然后交给物理层发出去。
上图所示就是数据链路层frame的结构
- Preamble:8 bytes, wakes up listeners(其实就是同步时钟)
- Destination address: 6 bytes, physical address of destination adapter
- Source address: 6 bytes, physical address of source adapter
- Type: 2 bytes, indicates what’s in the data field. E.g., IP or ARP
- Data: what are we sending. E.g., IP datagram, ARP request
- CRC: Cyclic redundant check to detect errors due to interference, attention, etc.
然后继续我们的ping命令产生的ICMP数据报文为例子,我们说了ICMP是Network层的协议,它其实利用了IP protocol来包装它,唯一跟IP protocol不同的只是data only标识了这是ICMP,没有其他的信息了。
当我们的ICMP的IP datagram生成后,交给数据链路层,我们上面的数据帧格式说明了,我们必须知道对方的MAC地址,换言之,我们想要使得数据链路层完成IP datagram的送达,就必须提供IP datagram里面目标IP对应的MAC地址。这里就是data link层解决的第一个问题:如何map IP address to MAC address?
Ethernet Frame Encapsulate ARP datagram
通过ARP(address resolution protocol),一看这名字就知道专为地址转化服务,首先普遍认为ARP协议是数据链路层的,但是也有很多argue说是网络层的,为什么?我们来看它的数据报文格式
- Hardware type: the type of the hardware address we are mapping to. E.g., Ethernet
- Protocol type: The type of network address we mapping from. IPV4
- Hardware size: the size of the hardware address for Ethernet 6 bytes.
- Protocol size: size of the network address (for IPV4 4 bytes)
- Operation: 1 for ARP request, 3 for ARP reply 、
上面的报文格式中,我们看到了有IP地址,那利用了IP地址的ARP显然就是跟IP协议处于同一层,但是不像IP协的是,ARP并没有利用这些IP地址,所以也广泛地认为它是数据链路层的协议。这里我们搁置争议,先来看ARP解决了什么问题?
就是寻址,在硬件设备的ARP module中会维护一张ARP table,它是一张IP MAC地址映射表 ,如果在encapsulate datagram的时候,此表中存在目标IP的MAC地址映射,那么我们就取过来,组装到数据帧中,如果没有我们就需要调用ARP协议,像LANs中broadcast一个request,相当于用大广播叫“IP为xxxx的,你的MAC地址是多少?”,此时由于是广播形式,所以LANs中的每一个host都能收到ARP request,然后将这个request交给ARP module,如果ARP module发现IP不匹配,就简单的drop这个request,啥也不做;如果发现跟自己匹配的化,就相对应的发一个reply给询问的host(此时是unicast了,点对点传播),然后相对应的检查自己的ARP table里有没有对应的IP MAC映射,如果没有,就加入一条记录(这里也是flooding有可能发生的地方,每个ARP module并不会检查数据报文的地址是不是存在,它简单的去匹配和回答,如果发现新的就添加到自己的table里,如果此时LANs中对一个host大量的发ARP request,并且都是伪装的IP和MAC,那么就会导致host的ARP table很快就满了)。同样的我们要注意到,这是在判断网络层交给数据链路层的目标IP是位于同一个subnet的,如果不是,那么就会将这个ARP request发个LANs的出口(router的网卡处)
好了,到这里,我们的ARP 协议解决了IP MAC地址的映射,我们此时的ICMP 数据报成功的获取了所有填充字段,可以发送了。
数据链路层并不提供可靠的data frame的传送,它只是best effort,类似于IP协议
ARP Spoofing
ARP欺骗是在datalink层常见的攻击方法,每一张Ethernet 网卡有一个硬件地址和IP地址。当数据链路层承接上层网络层的datagram时,是需要对方IP对应的硬件地址的。首先会在自己的routing table里寻找看是本地子网还是外网的,如果是本地子网那么就继续查找ARP cache table,找其中IP地址对应的硬件地址,如果没有就会广播ARP request,相对应的host收到request后会发ARP reply,这个reply一般是unicast的。
首先ARP Spoofing或者叫ARP poisoning是一种中间人攻击的方式。当target pc遭遇ARP Spoofing后,由于攻击发生得比较底层,所以较难detect。ARP Spoofing成功后,可以作为中间人监测通讯信息,也可以用于DDos攻击。
攻击步骤:
- 攻击者必须能够控制subnet中的一台设备
- 并且知道gateway的IP和subnet中target的IP
- 利用控制的设备发送假的ARP reply(由于ARP协议只是考虑了效率,所以对于任意来自于同一子网的ARP reply,都会直接更新到ARP table中),ARP reply中简单的将gateway地址对应的MAC地址换成自己的,将target的IP地址对应的MAC地址也换成自己的。
- 此时target的arp table和router的arp table都发生了改变(有两个不同的IP地址对应同一个MAC地址)
- 然后此时攻击者控制的设备可以选择充当中间人(相当于此时被控制的设备是一个router),也可以选择直接drop双方通讯的package,那么就是DDos 攻击。
总结
我们主要讨论的是物理层和数据链路层解决的问题,就是如何将上层的datagram包装成frame,然后发送到链路的一端。注意这里只是链路的一端,要是datagram不在同一个子网,我们就是发送到LANs的出口网关(通常是router),然后router再执行类似的操作。
总的来说IP层负责host到host的datagram的传送,而数据链路层负责在host到host的路径中,经过的两个点之间的传送。打个比方就是:IP曾就是旅游经理,负责规划你如何去加利福利亚旅游(从路径中选出一条),而数据链路层就是出租车司机,飞机机长,火车司机,负责这条路径中两个点的运输。