在NAT篇和拍案惊奇系列中,强叔多次提到配置NAT的同时要配置黑洞路由,避免路由环路,很多人对此不太理解,今天强叔就来为大家详细介绍其中缘由。
首先我们用eNSP模拟一个典型的源NAT环境:
NAT地址池地址是202.1.1.10,防火墙与路由器互联接口地址的掩码是30位,与NAT地址池地址不在同一网段。防火墙上配置了一条缺省路由,下一跳是202.1.1.2,这样就能把私网PC访问公网Server的报文送到路由器。为了保证公网Server的回程报文能够顺利到达防火墙,路由器上还要配置了一条到NAT地址池地址的路由。另外,防火墙上的NAT策略和安全策略也都配置完成了,在此不再赘述。
正常情况下,私网PC访问公网上的服务器Server,生成会话表,源地址也进行了转换,一切都没有问题。
此时,如果公网上的一台PC,主动访问防火墙上的NAT地址池地址,会发生什么情况呢?
我们在公网PC上执行ping 202.1.1.10命令,发现不能ping通:
显然,这是正常的结果。因为NAT地址池只有在转换私网地址的时候才会用到,也就是说,私网PC必须先发起访问请求,防火墙收到该请求后才会为其转换地址,NAT地址池地址并不对外提供任何单独的服务。所以当公网PC主动访问NAT地址池地址时,报文到达防火墙后,无法匹配会话表,防火墙肯定就会把报文丢弃了。
但实际情况远没有这么简单,我们在防火墙的GE0/0/1接口抓包,然后再次在公网PC上执行ping 202.1.1.10命令,这次我们使用-c参数,只发送一个ping报文:
GE0/0/1接口上的抓包信息如下:
嚯!不看不知道,一看吓一跳,居然抓到了这么多ICMP报文。经过分析发现,报文的TTL值逐一递减,直到变为1。我们都知道,TTL是报文的生存时间,每经过一台设备的转发,TTL的值减1,当TTL的值为0时,就会被设备丢弃。这说明公网PC主动访问NAT地址池地址的报文,在防火墙和路由器之间相互转发,直到TTL变成0之后,被最后收到该报文的那台设备丢弃。
我们来梳理一下整个过程:
1、路由器收到公网PC访问NAT地址池地址的报文后,发现目的地址不是自己的直连网段,因此查找路由,发送到防火墙。
2、防火墙收到报文后,该报文不属于私网访问公网的回程报文,无法匹配到会话表,同时目的地址也不是自己的直连网段(防火墙没有意识到该报文的目的地址是自己的NAT地址池地址),只能根据缺省路由来转发。因为报文从同一接口入和出,相当于在同一个安全区域流动,缺省情况下也不受安全策略的控制,就这样报文又从GE0/0/1接口送出去了。
3、路由器收到报文后,查找路由,还是发送至防火墙,如此反复。这个可怜的报文像皮球一样被两台设备踢来踢去,最终被残忍丢弃,憾别网络。。。。。
下面我们来看一下配置了黑洞路由的情况。首先在防火墙上配置一条目的地址是NAT地址池地址的黑洞路由,为了避免这条黑洞路由影响其他业务,我们将掩码配置成32位,精确匹配202.1.1.10这个地址:
[FW] ip route-static 202.1.1.10 32 NULL 0
然后在防火墙的GE0/0/1接口上开启抓包,在公网PC上执行ping 202.1.1.10 -c 1命令,还是只发送一个ping报文,查看抓包信息:
只抓到了一个ICMP报文,说明防火墙收到路由器发送过来的报文后,匹配到了黑洞路由,直接将报文丢弃了。此时就不会在防火墙和路由器之间产生路由环路,即使防火墙收到再多的同类报文,都会送到黑洞中,一去不复返。并且,这条黑洞路由不会影响正常业务,私网PC还是可以正常访问公网Server。
到这里大家可能会问了,没有配置黑洞路由时,报文最终也会被丢弃,没啥问题啊?上面我们只是用了一个ping报文来演示这个过程,试想一下,如果公网上的捣乱分子利用成千上万的PC主动向NAT地址池地址发起大量访问,无数的报文就会在防火墙和路由器之间循环转发,占用链路带宽资源,同时防火墙和路由器将会消耗大量的系统资源来处理这些报文,就可能导致无法处理正常的业务。
所以,当防火墙上NAT地址池地址和公网接口地址不在同一网段时,必须配置黑洞路由,避免在防火墙和路由器之间产生路由环路。
那么如果NAT地址池地址和公网接口地址在同一网段时,还会有这个问题吗?我们再来验证一下。
首先,将防火墙和路由器互联的两个接口的掩码修改为24位,这样接口地址和NAT地址池地址就在同一网段了,然后去掉黑洞路由的配置,接下来在防火墙的GE0/0/1接口抓包,在公网PC执行ping 202.1.1.10 -c 1命令,查看抓包信息:
我们发现,只抓到了三个ARP报文和一个ICMP报文,公网PC访问NAT地址池地址的报文没有在防火墙和路由之间相互转发。梳理整个过程:
1、路由器收到公网PC访问NAT地址池地址的报文后,发现目的地址属于自己的直连网段,发送ARP请求,防火墙会回应这个ARP请求,前两个ARP报文就是来完成了这一交互过程的。然后路由器使用防火墙告知的MAC地址封装报文,发送至防火墙。
2、防火墙收到报文后,发现报文的目的地址和自己的GE0/0/1接口在同一网段,直接发送ARP请求报文(第三个ARP报文),寻找该地址的MAC地址(防火墙依然没有意识到该报文的目的地址是自己的NAT地址池地址)。但是网络中其它设备都没有配置这个地址,肯定就不会回应,最终防火墙将报文丢弃。
所以说,在这种情况下不会产生路由环路。但是如果公网上的捣乱分子发起大量访问时,防火墙将发送大量的ARP请求报文,也会消耗系统资源。所以,当防火墙上NAT地址池地址和公网接口地址在同一网段时,建议也配置黑洞路由,避免防火墙发送ARP请求报文,节省防火墙的系统资源。
下面是配置黑洞路由后的抓包信息,可以看到,防火墙没有再发送ARP请求报文:
还有一种极端情况,我们配置源NAT时,可以直接把公网接口地址作为转换后地址(easy-ip方式),也可以把公网接口地址配置成地址池地址。这样,NAT转换使用的地址和公网接口地址就是同一个地址了。在这种情况下,需要配置黑洞路由吗?我们来分析一下整个流程:防火墙收到公网PC的报文后,发现是访问自身的报文,这时候就取决于公网接口所属安全区域和Local安全区域之间的安全策略,安全策略允许通过,就处理;安全策略不允许通过,就丢弃。不会产生路由环路,也不需要配置黑洞路由。
看到这里,聪明的小伙伴肯定会问,NAT Server有没有这个问题啊?强叔告诉大家,NAT Server也存在路由环路的问题,不过发生路由环路的前提条件比较特殊,要看NAT Server是怎样配置的。下面是一个典型的NAT Server组网环境,我们先来看一下NAT Server的Global地址和公网接口地址不在同一网段的情况。
如果我们在防火墙上配置了一条粗犷型的NAT Server,将私网Server全部发布到公网,如:
[FW] nat server global 202.1.1.20 inside 192.168.0.20
公网PC访问202.1.1.20的报文,目的地址都会被转换成192.168.0.20,然后发送给私网Server,这个时候自然不会产生路由环路。
但是如果我们配置了一条精细化的NAT Server,只把特定的端口发布到公网上,如:
[FW] nat server protocol tcp 202.1.1.20 80 inside 192.168.0.20 80
此时如果公网PC不按常理出牌,没有访问202.1.1.20的80端口,而是使用ping命令访问202.1.1.20,防火墙收到该报文后,既无法匹配Server-map表,也无法匹配会话表,就只能查找路由转发,从GE0/0/1接口送出去。而路由器收到报文后,还是要送到防火墙,这样依然会产生路由环路:
所以,当防火墙上配置了特定协议和端口的NAT Server并且NAT Server的Global地址和公网接口地址不在同一网段时,必须配置黑洞路由,避免在防火墙和路由器之间产生路由环路。
如果NAT Server的Global地址和公网接口地址在同一网段,防火墙收到公网PC的ping报文后,会发送ARP请求报文,这个过程就和前面讲过的NAT的情况是一样的。同理,当防火墙上配置了特定协议和端口的NAT Server并且NAT Server的Global地址和公网接口地址在同一网段时,建议也配置黑洞路由,避免防火墙发送ARP请求报文,节省防火墙的系统资源。
同样,我们配置NAT Server时,也可以把公网接口地址配置成Global地址。此时,防火墙收到公网PC的报文后,如果能匹配上Server-map表,就转换目的地址,然后转发到私网;如果不能匹配上Server-map表,就会认为是访问自身的报文,由公网接口所属安全区域和Local安全区域之间的安全策略决定如何处理。不会产生路由环路,也不需要配置黑洞路由。
讲到这里,相信大家一定明白了配置黑洞路由的原因,是不是感觉内功又提升了啊~~我们再总结一下,对于源NAT来说:
如果NAT地址池地址与公网接口地址不在同一网段,必须配置黑洞路由;
如果NAT地址池地址与公网接口地址在同一网段,建议也配置黑洞路由。
对于配置了特定协议和端口的NAT Server来说:
如果NAT Server的Global地址与公网接口地址不在同一网段,必须配置黑洞路由;
如果NAT Server的Global地址与公网接口地址在同一网段,建议也配置黑洞路由。
最后,大家再来跟强叔默念一下本篇内功心法的口诀:地址不在同网段,报文无奈来回走,黑洞路由必须配,防止环路显身手;地址虽在同网段,但是会发ARP请求,黑洞路由也配上,节省资源不用愁!
【扩展阅读】
除了防止路由环路、节省设备的系统资源,其实黑洞路由还有一个作用,那就是在防火墙上引入到OSPF中,发布给路由器。
我们知道,当NAT地址池地址或NAT Server的Global地址与防火墙和路由器互联接口的地址不在同一网段时,需要在路由器上配置到NAT地址池地址或NAT Server的Global地址的静态路由,保证路由器可以把去往NAT地址池地址或NAT Server的Global地址的报文发送到防火墙。
如果防火墙和路由器之间运行OSPF协议,那么就可以通过OSPF协议来学习路由,减少手动配置的工作量。但是NAT地址池地址和NAT Server的Global地址不同于接口地址,无法在OSPF中通过network的方式发布出去,那么路由器如何才能学习到路由呢?
此时就可以通过在防火墙的OSPF中引入静态路由的方式,把黑洞路由引入到OSPF中,然后通过OSPF发布给路由器。这样,路由器就知道了去往NAT地址池地址或NAT Server的Global地址的报文都要发送到防火墙上(注意,是发送到防火墙,而不是发送到黑洞中)。
以NAT Server的组网为例,NAT Server的Global地址和公网接口地址不在同一网段,防火墙和路由器都运行OSPF协议,在防火墙上的OSPF中引入静态路由:
#
ospf 100
import-route static
area 0.0.0.0
network 202.1.1.0 0.0.0.3
#
这时路由器就可以学习到去往NAT Server的Global地址的路由: