TCP/IP协议详解卷1学习笔记系列3-IP路由
第1卷第九章 IP路由
本章讲述的是做为TCP/IP协议簇的基础。IP路由保证能为数据报找到正确的发送路径。假如实在找不到,则通知发送方发放失败。
在找路过程中所作用的信息,由两方面来维护:每个主机都维护有自身的路由表(windows下用 route print打印出当前的路由表)。由于一般主机上只有一个网卡,因此路由表都比较简单,包含一个环回接口(127.0.0.1)和当前使用的IP,假如连网卡也没有,那就只有环回地址了。对所有发往127.0.0.1,localhost的数据报都在发往链路层(常见的就是以太网驱动层)前,就转往IP输入表了。而对发往自身IP的数据在发到链路层后,链路层在检查到这个地址是自身后,再发往IP输入表。
对发往其他地址的数据报,选用的接口就是网卡,全部发到网卡上。默认路由也是这个接口。
假如安装了多张网卡,windows的服务器版可以开启路由转发功能,也就是可以当做路由器用。假如只装了一张网卡,也使用转发功能,而实际上还是“从哪里来,到哪里去”,根本就达不到“选路”的目的。
这样主机在收到一个数据报时,先检查是不是发给自己的。假如是,就是正常的通讯,直接处理。假如不是,就根据是否可以转发的选项(是否开启路由转发功能),来决定是直接丢弃数据报,还是从网络接口中找一个合适的转发出去。
假如决定转发,这时才真正涉及到“找路”。主机和路由器各自都有一个路由表。首先检查路由表里的指向主机的那些表项,看是不是有哪一个条目就是要发往的目的地址。假如找到了,直接发往这个主机。假如找不到,再查指向网络号的那些表项,看主机要发往的网络是不是已经有记录。假如找到了,就发往这个网络要经过的接口。假如这些都找不到,就把这个数据报发往默认路由,由默认路由去处理。通常默认路由的表项更多,有更多的信息能找到要发往的目的地。假如默认路由还找不到,就再发往它的默认路由,一直到顶层。顶层的核心路由器假如还找不到,那就表明这个数据报确实是找不到目的地了,路由器返回一个ICMP报文,告诉发送方主机“网络不可达”,或“主机不可达”。具体信息根据路由器来决定,不过收到“主机不可达”的居多。
这些说起来是比较烦的。想像一个生活中的例子:
我想坐火车到拉萨去,到杭州火车站去坐车。杭州没有直达的车次(在青藏线通车前,全国都没有:)),也就相当于它找不到主机“拉萨”,也不知道它属哪个铁路局(网络号),它把我送到中转站徐州(默认路由)。徐州站同样找不到,但它知道主机“拉萨”属西部,也许网络号“郑州局”知道,于是把我打发到了“郑州”。而郑州也没有直达的车,它再把我打发到更近一点的“西宁”。然后在西宁火车站,得知青藏线还没有全线通车,此路不通。于是告知我“主机不可达”,这拉萨去不成了。
在生活中我就只得再回到杭州老老实实地过日子了。而在网络上,发到“西宁”的数据报是不会再发回来的,路由器(火车站)只是简单地把“我”扔掉,然后告知杭州警方。
这样就是一个找路的过程。假如在最后终于找到了,当然皆大欢喜,然后就可以“握手言欢”,找到组织了。接下来的事就与路由无关了。
从这个过程可以看到路由表项的重要。假如路由表的信息很具体,每个主机都能找到,那么只要发往路由器,所有的数据报都能顺利到达,就像杭州站有发往全国各地的车。然而实际上这样的要求不现实。网络上的主机不可胜数,就像全国的火车站多如牛毛,要做到每个主机都有一个项目,要求路由器有极大的容量来存放这些记录,而在这庞大的路由表中查找条目的效率也成问题。于是现在的路由器构成层次结构,每一层的路由器保存局部的路由信息。对自己处理不了的数据报,发往默认的路由去处理,这样对单台路由器的要求可以降低一些。
然后就是路由信息的创建与更新问题了。主机的开机关机,路由器的开机关机,这些都是不可预知的,也就是说路由信息可能是不确定的,这一分钟这条路还是通的,下一分钟说不定就不通了(关机了,崩溃了,被攻击了。。。)。这样造成的路由信息失效需要及时更新,以免造成错误的路由。
路由基本信息的创建一般是在系统启动过程中完成,如默认路由的配置。用 route add 命令可以手动加入一个静态路由。更多的路由信息是在通信过程不断充实的,也就是路由器自己慢慢“学”到的。这个跟ARP有一点类似的地方。在局域网内,假如要发数据报到另一台主机,例如从A发到B。假如一开始A不知道B在哪里,就发一个ARP询问B在哪里。B收到后回答自己的MAC地址,然后ARP守护程序会把这个MAC与B机的IP组合成一项保存起来。下次有数据要发到B时,就不用再问了,直接发到对应的MAC地址(用arp -a 可以查到当前的arp表项)。路由器也类似,假如它知道有一个接口可以发送,就把这个接口保存起来。不同的是,ARP工作在链路层,在IP层以下,而路由器处理起这些信息来,比ARP守护程序要复杂得多。
路由器是可以“学习”的。学习的是其他路由器发出的路由通告报文(ICMP数据报)。路由器大约9~10分钟发一次路由通告报文,收到报文的路由器就更新自己的相应条目。这种学习是被动的。而在路由器启动时,会发出路由请求报文(同样是ICMP数据报),其他路由器会做出响应,回复路由通告报文,这样路由器就可以主动学习其他路由器上的路由信息了。
另一种修改路由信息的途径是ICMP重定向报文。还以上面做例子,我被杭州站送到徐州后,徐州站觉得我应该被直接送到郑州,而不必跑一趟冤枉路,于是它通知杭州站,以后对所有象我这样的旅客,直接送到郑州就行了。杭州收到后,更新路由信息,也就是重新定向。
当然主机接收ICMP重定向要求并更新路由信息的要求要严格许多。书上列出了4.4BSD系统接收ICMP重定向的四个要求。没接触过这个系统,而且书是几年前写的,现在的网络环境比当时要复杂。因为这些环节是轻易被人恶意利用的。
书上的内容说完,说些我感爱好的方面。
arp和路由都是用来探路的。arp用于局域网,而路由用于广域网(不是严格的划分,大致上是这样)。为了灵活,这些信息都是可以通过icmp数据报修改的。而一旦能被修改,以后所有相关的数据流量就牵引到其他地方去了。这样有隐患,很可能被人利用。
arp协议规定,假如收到其他主机发出的arp数据报,就要以数据报中的IP与MAC对应信息更新arp缓存中已经保存的信息,以后发到这个IP的信息发到新的MAC上。这样就可以通过构造ICMP数据报,伪造一个arp信息,实施arp欺骗。
现在流行的arp欺骗步骤是这样的:假设A与B、C同是一个局域网,各自有IP地址。A对B是完全信任的,而对C则有限制,例如过滤所有来自C的数据,或者限制一些端口等,反正就是C不如B有地位。而C觉得不平,想得到B同等待遇(具体的原因多种多样,反正结果是一样)。这样C就开始做手脚了,直接向治理员要求肯定不行,只好暗地里取代B的位置。
1.首先把B搞死机。假如B还在网上,对C后面的arp欺骗有妨碍。
2.把C自己改成B的IP,这样就可以骗过A,让A以为真的是B。
3.发放伪造的arp包,把B的IP与C的MAC联系起来。
4.所有主机收到arp包,并根据内容更新arp缓存,于是所有发往B的数据现在改发到C,所有收到C发出数据的主机都以为是B发过来的。而B这时正死机呢,一点都不知道。
这种欺骗实施起来有难度。只能在局域网内使用。首先要搞定B,假如B拿不下,后面就很难。而且针对IP开放服务的越来越来越少,一般都附加有其他的限制,顶替掉B也难有作为。
对这种欺骗我知道的有两个案例:一个是在一个论坛上,有网友说他用这种方法做网络治理软件,用它来屏蔽一些网站,所有发到被屏蔽网站IP的请求转到别的网站,不使用代理服务器。这个思路不错。另一个是前两天(9月15日下午),某安全会议召开期间,站点“被黑”,网页不能正常打开。据网站成员说,是托管服务商的另外一台主机被黑,用arp欺骗把访问正常网页的请求转移到被黑的主机上。于是现场实施一场“攻防对抗”,一个不断地发欺骗报文,把访问转移;另一个不断发正常报文,把访问夺回来。于是在这段时间访问网页时,就出现了一下子出现正常网页,刷新时变成变黑的页面,再刷新又正常的奇观。可惜当时我正在上班,没有亲眼看到。
路由信息同样有伪造的可能。路由通知信息可以更新其他路由器的路由表。假如发出一个伪造的路由通知信息,那就破坏了路由器的正常路由表。这个实现起来比较难,而ICMP重定向的实现起来的难度就要小许多。
arp欺骗只能在局域网内实现。假如要在广域网上达到相同的目的,就必须结合ICMP欺骗了。
用arp欺骗可以把流量转移,但是转移时有个限制,不能转移到路由器上,也就是arp信息是不能跨路由的(不同于代理ARP)。这样即使把其他主机的arp信息刷新成路由器的MAC,发送数据时还是只在局域网内寻址,就是不往路由器那里发。这时必须再发一个ICMP欺骗,说发到路由器的MAC才是正确的。主机收到这个消息后,才能达到目的,C完全取代B。之后的事情,就象入侵者的心情了。
从这个意义上,可以实现任何机器的Sniffer(跟踪所有通讯数据)。
上面说的这些,我现在还只是在概念、原理层面上的了解,以及对这些方面了解的总结。要动手实现水平还不够,还得学习。网络抓包现在是会了,但是要谈协议分析还早。连构造 RAW Socket都不太会,要玩其他就更是扯远了。