思科、华为防火墙做端口回流解决内网主机无法通过公网访问内网服务的问题

问题产生原因分析:
 
网络环境介绍:
公司内网有一台web服务器,地址是192.168.100.100,web服务端口为80,并且为这台web服务器申请了DNS A记录的域名解析服务,解析记录是公司出口ip地址100.100.100.100。在办公区网络环境里,还有内网192.168.10.0网段,需要通过申请的域名来访问公司内网的192.168.100.100的web服务。
做法是在防火墙的出口,做一条端口映射,100.100.100.100:80到192.168.100.100:80的端口映射。
问题来了,做好端口映射以后,其他外部网络通过域名访问公司的web服务是正常的,但是公司内网用户通过域名访问公司自己的web服务,却无法访问;而公司内网用户通过192.168.100.100:80私有地址访问,是正常的。这种情况,就是因为做好端口映射以后,访问web服务的流量在响应的时候流量没有回流到防火墙导致的。
 
原因分析:
如上图,假如是192.168.10.10通过申请的域名访问192.168.100.100的web服务。这里假设访问的源端口是10000,目标端口是80,数据包分析如下:
C2主机发起web请求.因为通过域名访问的,DNS解析服务正常,那么访问目标就是100.100.100.100:80
192.168.10.10:10000--->100.100.100.100:80
 
数据包最终会被路由到防火墙上,防火墙检查访问的目的地址,匹配到它的端口映射策略,将目标地址改为对192.168.100.100的访问,建立起一个针对目标ip地址转换的NAT会话表
192.168.10.10:10000--->192.168.100.100:80
 
然后数据包到会被转发到192.168.100.100服务器上并会响应192.168.10.10主机的请求,将上述访问的源目ip地址及端口进行倒转,并将数据包交给它的网关处理,图中就是R1路由器
192.168.100.100:80--->192.168.10.10:10000
 
R1路由器检查访问者的源ip和目标ip地址,发现目标ip地址是192.168.10.10,是R1路由器一个可路由的内网ip地址,就会将数据包直接路由到C2主机上
C2主机接收到数据包,检查数据包的源ip和端口是192.168.100.100:80,发现其本身并没有这样一个http会话与之相匹配,就是说C2主机并没有主动发起对192.168.100.100:80的访问,发起的是对100.100.100.100:80的访问,那么C2主机就会丢弃这个数据包,导致内网用户通过域名或者公网ip地址访问自己的内网服务器不通的现象。
192.168.100.100:80--->192.168.10.10:10000
 
上述就是造成我们开头所说问题的原因。发生上述问题的原因,就是因为其R1路由器发现响应数据包的目的ip地址是内网一个可直接路由的地址,就会直接在内网进行路由转发,而不是将数据包交给防火墙进行路由转发。
不要认为这是bug,这是正常现象,任何设备只要做了端口映射,都绕不开这个问题,因为TCP/IP协议栈就是这样工作的。你要推倒重来,除非自己去设计一套网络协议标准,况且在现有的TCP/IP的协议框架下,这个问题又不是说不能解决。那为何有的设备不用做端口回流呢?那是因为有的设备在你做端口映射的时候,偷偷地把端口回流的问题也给你解决了。然而你也不要以为它们帮你做了端口回流,你就认为那些设备是好设备,感觉好高端,那你错了,我很少见企业级设备偷偷地帮你解决这个问题的(不是说没有,一般是应用层网络设备有这个),都是需要你主动去处理解决,这也体现了它们设备高度可定制性及扩展性。
你要高度可定制性和扩展性,那就要牺牲人性化的设计,需要专业人员去帮你做业务上的定制;你要人性化,自己点点鼠标就能把问题解决,那它就不可能在可定制性和扩展性上给你太多,这个世界上的事情也是如此,没有十全十美。
 
解决方法:
这里介绍下思科防火墙和华为防火墙上如何解决这个问题。至于其他厂家的设备或者路由器等网络设备,如何解决,可以自行查阅相关资料,解决的原理都一样
这里只介绍其中一个解决方法,还有其他方法,可以自行查阅相关资料
 
解决方法的思路:内网主机在访问的时候,将web服务的响应流量回流到防火墙上来,接受防火墙的处理。就是说,在流量经过防火墙的时候,将源地址做一个修改,使得R1路由器在路由数据包的时候,还把这个数据包路由到防火墙上来,而不是在内网直接路由;防火墙上有记录它所做的相应修改(做源地址转换,并维护这个NAT会话表即可),再把之前的修改给改回来,再转发给内网主机即可。
内网主机对通过公网对内网服务器访问的时候,流量在经过防火墙时,将内网主机的ip地址修改为一个外网ip地址(源NAT转换),并做好及维护相应的NAT会话的记录,这样服务器在接收到数据包之后,发现源ip地址是一个外网ip地址,这样数据流量会回流到防火墙,防火墙检查相应的源NAT转换策略,发现可以匹配,则进行源NAT的还原,并经数据包路由到内网的主机中
 
思科防火墙在做端口映射的时候,分为static(inside,outside)和static(inside,inside),方向不同。但是华为防火墙没有这个问题,因此思科在解决这个问题时,有下面两个关键步骤,而华为防火墙只需要下面第一步(准确来说,华为防火墙只是用的第一步的思路,实现方式和思科防火墙略微有些区别)即可。
第一步:内网192.168.10.0网段对100.100.100.100的访问的时候,将源地址做一个转换,转换为防火墙内网口inside对100.100.100.100的访问。
这一步你可以理解为用防火墙的内网inside接口的地址去访问100.100.100.100。
之前做的全局NAT的转换,内网192.168.10.10对所有外网的访问,是转换为防火墙outside口对外网的访问,即防火墙outside代理防火墙内网中的所有主机去访问外网,例如百度
第二步:内网192.168.10.0网段对100.100.100.100:80的访问,将目标地址做一个转换,转换为对内网192.168.100.100:80的访问。
这一步是做LAN到LAN的端口映射
 
思科防火墙:这里是基于思科防火墙8.2系统版本的配置,新版本配置有所改变,但是解决方法的原理类似
先做最基础的配置,这里是我们平时上网说必须要的配置
1、全局的NAT源地址转换,注意下面数字要对应。这一步主要是为了让内网用户可以正常访问外网用的
# nat (inside) 1 0.0.0.0 0.0.0.0            //这条命令匹配了所有ip地址
# global (outside) 1 interface            //对上面匹配的IP地址访问外网的流量,做源地址转换,源地址是interface outside接口的ip地址,即100.100.100.100
 
2、做端口映射(目的ip地址转换):我们做的web服务是为我们的用户提供服务的,因此我们需要做一个端口映射,能够让用户访问我们的web服务
# static (inside,outside) tcp 100.100.100.100 80 192.168.100.100 80 netmask 255.255.255.255 //外网outside区域网络访问100.100.100.100:80的时候,将转换对192.168.100.100:80的访问
 
3、内网192.168.10.0网段访问100.100.100.100的时候,也做源地址转换,但是区别上面的第1步,这里将源地址改为防火墙的内网口inside口
# access-list 100 extended permit ip 192.168.10.0 255.255.255.0 host 100.100.100.100 //匹配公司内网192.168.10.0/24访问公网ip100.100.100.100的流量
# nat (inside) 10 access-list 100
# global (inside) 10 interface //对捕获的流量做源地址转换,转换成interface inside接口的ip地址。就是说内网访问100.100.100.100的流量的源地址,转换为防火墙内网口的地址,变为防火墙inside口对web服务的访问。
注意:如果这里是路由器或者其他网关设备的话,需要将interface换成这台路由器或者网关设备真实的ip地址,这里思科防火墙可以使用接口名称代替
 
4、内网192.168.10.0网段对100.100.100.100:80的访问,做目的ip地址及端口的转换,但是这里区别上面的第二步,这里将目的地址改为内网服务器的ip地址,即192.168.100.100:80
# static (inside,inside) tcp 100.100.100.100 80 192.168.100.100 80 netmask 255.255.255.255 // //内网(inside区域)的网络对100.100.100.100:80的访问转换为对192.168.100.100:80的访问
 
5、允许相同安全级别之间的接口可以互相转发数据
# same-security-traffic permit intra-interface
防火墙多一个这个步骤,路由器等其他网关设备没有
 
华为防火墙
1、全局NAT地址转换。这一步主要是为了让内网用户可以正常访问外网用的
# nat-policy interzone trust untrust outbound // 注意NAT策略方向
# policy 0
# action source-nat // 是做源地址转换
# policy source 192.168.0.0 mask 255.255.0.0 // 匹配内网所有主机ip
# easy-ip GigabitEthernet0/0/1 // 将源地址转换为防火墙GigabitEthernet0/0/1接口的ip地址(在企业,一般这个接口都是企业出口ip地址)
 
2、端口映射:
# nat server 6 protocol tcp global 100.100.100.100 www inside 192.168.100.100 www
 
3、创建地址池
# nat address-group 1 1.1.1.1 1.1.1.2 // ip地址为1.1.1.1-1.1.1.2。咨询过华为工程师,这里的地址池可以任意写,但是必须保证在全网内唯一,数据可被路由到防火墙即可。不可以和上面的easy-ip重复
 
4、做域内NAT,注意和上面第二步NAT的区别,策略方向不一样
# nat-policy zone trust
# policy 1
# action source-nat
# policy source 192.168.0.0 mask 16 // 这里匹配需要通过公网访问的所有内网主机ip
# policy destination 192.168.100.100 mask 32 // 这里匹配,内网主机访问哪个ip的时候,执行这个NAT(可以和上面一样,写地址段)
# address-group 1 // 匹配以后,将源地址转换成这个地址池里的地址,注意1和上面的地址池索引相对应
 
说明:华为防火墙做好域间的策略,保证网络访问正常,这属于其他防火墙的知识范围,不做过多讨论。
上述华为防火墙端口回流最好以后,内网主机用户通过公网访问,还是不行。具体也咨询了华为工程师,把配置信息也发给他们看了下,他们检查配置也说配置没问题,找不出问题所在。通过测试并查看防火墙的会话表,发现内网主机发起访问的时候,主机的源地址没有执行转换,就是上面的第4步没有生效,估计是防火墙版本的一个bug吧。有华为防火墙大神的,可以帮忙指出问题所在。
 
说下华为防火墙和思科防火墙解决这个问题的思路上的一点不同:
思科防火墙:
思科防火墙在内网通过公网访问内网web服务的时候,当流量到达防火墙以后,防火墙偷偷地数据包的源地址改成防火墙inside接口的地址了,这样web服务器收到数据包的时候,就会响应这个数据包,把这个数据包响应给防火墙,而不是内网的主机。防火墙收到响应数据包以后,再偷偷地将数据包的源ip地址(此时已经变成目的ip地址了)改成内网主机的ip地址,然后转发给内网主机。
 
华为防火墙:
华为防火墙在内网通过公网访问内网web服务的时候,当流量到达防火墙后,防火墙像思科防火墙一样,也会偷偷将数据包的源地址改成配置好的地址池中的一个ip地址(一般是一个公网地址,只要全局唯一即可);web服务器收到数据包的时候,就会响应这个数据包,因为是地址池内的地址,在内网不可路由,数据就会被路由到防火墙上,防火墙再次偷偷地将数据包的源ip地址(此时也应变成目的ip地址了)修改成内网主机的ip地址,然后再发给内网主机。
 
思科防火墙和华为防火墙在处理这个问题的时候,思路上有点不同。但是都是内网主机通过公网访问内网web服务的时候,偷偷将主机ip地址修改成一个在内网必须路由到防火墙的一个ip地址(就是说接受防火墙的控制),然后web服务响应数据会回流到防火墙,最后经防火墙处理,转发给内网主机。
 
台上十分钟,台下十年功。在控制台上敲的几下键盘,写的几行命令,台下的你可能要花上大半年甚至一两年的时间,去了解它背后实现的原理和遇到问题的解决方法。你可能要去了解整个TCP/IP协议栈的工作方式、防火墙的工作方式及工作原理、广域网以及局域网技术原理等等。总之,学无止境,越学越感觉自己之前无知。
 
 
 
 

 

posted @ 2017-09-19 16:42 wangpanda6 阅读(...) 评论(...) 编辑 收藏