Linux服务器使用iptables做了DNAT以后发现内网的用户不能通过域名访问WEB服务器,只能通过web服务器的内网ip来访问,这个问题相信有很多人都遇到了,那么今天我就给大家来分析一下为什么会出现内网用户不能通过域名访问WEB服务器。首先按照下面的实验拓扑把基础的环境搭建好。
实验拓扑图如下:
首先我们有内网服务器 192.168.1.1 内网pc:192.168.1.2 网关就是防火墙的内网接口eth0:192.168.1.254 防火墙的外网接口eth1:200.1.1.1 DNS服务器为:200.1.1.2 内网用户的dns指向200.1.1.2
首先我们做了SNAT 来保证内网用户可以正常访问外网,为了使得我们的内网服务器可以对外发布,我们在防火墙做一个DNAT:iptables -t nat -A PREROUTING -i eth1 -d 200.1.1.1 -p tcp --dport 80 -j DNAT --to 192.168.1.1:80
在dns服务器上面设置A记录 www.a.com 解析到200.1.1.1 ,web服务器绑定www.a.com 域名。
然后我们外网可以正常通过域名(www.a.com)访问内网服务器,可是内网用户不能通过域名(www.a.com)访问服务器,只能通过192.168.1.1 来访问服务器,为了使得内网用户也能通过域名访问内部服务器,我们需要在防火墙上做一些配置。
首先我们来分析一下,为什么内网用户不能通过域名访问服务器?
首先我们192.168.1.1 发起一个域名解析请求正常解析之后我们发现,域名对应的服务器ip是200.1.1.1 ,然后192.168.1.1访问200.1.1.1,经过网关之后,我们我们发现我们做的DNAT是针对eth1进来的数据做的DNAT,并没有做eth0的DNAT,内网pc直接强行访问200.1.1.1的80端口,可以200.1.1.1的80并没有开。所以访问失败。
有的人会说,这个简单啊,我们直接在添加一个“iptables -t nat -A PREROUTING -i eth0 -d 200.1.1.1 -p tcp --dport 80 -j DNAT --to 192.168.1.1:80” 让从内网来的数据也DNAT,这样好像是可以了,但是我们在内网pc访问还是失败,为什么呢?我们分析一下包的走向。
首先内网pc访问到了防火墙,好我们做了eth0的DNAT,我们就是从eth0进来的数据,条件符合,我们会转向192.168.1.1,内网服务器收到包,一看是找我的,我回应,可是内网服务器发现,来的包的源ip是我的内网用户,而且是一个网段,服务器就会直接给内网pc回应,到这个我们发现好像可以访问了,但是内网pc的得到的数据包的源IP是什么呢?是192.168.1.1 因为是内网服务器给内网pc发的数据,可以内网pc在发起连接的时候目的ip是200.1.1.1 现在回来的源ip并不是200.1.1.1 所以会丢弃这个包。还是不行。
其实我们需要解决一下snat的问题,我们发现内网pc并没有做snat,为什么呢?因为我访问数据不需要从eth1出去,所以就不做snat,我们强制进行snat,"iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 192.168.1.1 -p tcp --dport 80 -j SNAT --to 192.168.1.254"
就是如果内网的数据进来防火墙,在做完DNAT,我发现访问的是192.168.1.1 然后我们紧接着做一个snat,那么我们去访问服务器时的源ip就是192.168.1.254,服务器收到以后,响应之后发回给192.168.1.254,因为做了SNAT有端口的对应,就能直接找到内网的pc所以通信正常。
注意: iptables -t nat -A PREROUTING -i eth0 -d 200.1.1.1 -p tcp --dport 80 -j DNAT --to 192.168.1.1:80 这个一定是插入,如果把之前的那个DNAT删除,那么外网就不能访问服务器了。iptables -t nat -A PREROUTING -i eth1 -d 200.1.1.1 -p tcp --dport 80 -j DNAT --to 192.168.1.1:80 这2个是一起存在的。或者我们简化一下。我们直接合并成一条。 iptables -t nat -A PREROUTING -d 200.1.1.1 -p tcp --dport 80 -j DNAT --to 192.168.1.1:80 我们在语句里面不要加入-i 就是不指定是哪个网卡接口进来的数据就ok了。