iptables DNAT功能介绍及案例分析

来源:互联网 发布:简单好记的域名 编辑:程序博客网 时间:2024/05/24 07:18

iptables DNAT功能就是重写包的目的IP地址。如果一个包被匹配了,那么它所有的包都会被自动转换,然后被路由到正确的主机或网络。

DNAT target是非常有用的一项功能。  如果我的Web服务器在LAN内部,而且没有可在Internet上使用的公网IP地址,那就可以使用DNAT让防火墙把所有到它自己:80(web)端口的包转发给LAN内部真正的Web服务器。

另外目的地址也可以是一个范围,这样的话DNAT会为每一次请求随机分配一个地址。所以,我们可以用这个DNAT做简单的负载平衡。

注意,DNAT 只能用在nat表的PREROUTING和OUTPUT链中,或者是被这两条链调用的链里。

DNAT 选项: --to-destination
范例:iptables -t nat -A PREROUTING -p tcp -d 202.123.45.67 --dport 80 -j DNAT --to-destination 192.168.10.8:80
范例说明:
-t nat 指定要在nat表中添加一条PREROUTING链  -p tcp -d 15.45.23.67 --dport 80 所有要送往202.123.45.67的80端口的数据包 -j DNAT --to-destination 192.168.10.8:80 被DNAT转向192.168.10.8:80端口(也就是LAN内的web服务器上)
这是一个典型的将内部web服务器通过防火墙202.123.45.67发布的案例。要注意:--dport的使用只有先用-p指定了TCP或 UDP协议才能使用。

因为DNAT的处理过程要做很多工作,所以我们再通过一个例子来大致理解一下它是如何工作的:
比如,我想通过Internet连接发布我们的网站,但是web server在我们的内网里,而且我们对外只有一个合法的IP,就是防火墙那个对外的IP(eth1=202.123.45.67)。防火墙还有一个内网的IP($AIP0=192.168.10.1),web server的IP也是内网的($BIP=192.168.10.8)为了完成我们发布的要求,要做的第一件事就是把下面的这个简单的规则加入到nat表的PREROUTING链中:

 iptables -t nat -A PREROUTING -d 202.123.45.67 -p tcp --dport 80 -j DNAT --to-destination 192.168.10.8:80

现在,所有从Internet到防火墙的80端口去的包都会被转发(被DNAT )到在内网的web服务器上。
注意哦:是所有internet来的包会被转发。如果你在Internet上试验一下,一切正常吧。OK 我们完成了web的对外发布。

这时我们再从内网里试验一下“C计算机”通过internet访问web服务器,肯定是不能用的。这是路由的问题,下面我们来好好分析这个问题。
为了容易阅读,我们把在外网上访问我们服务器的那台机子的IP地址记为“D计算机”。
 包从地址为D的机子出发——》去往地址为eth1=202.123.45.67(防火墙)——》包到达防火墙——》防火墙匹配此包为DNAT规则——》转发这个包到eth0—— 》包离开防火墙A向192.168.10.8 web server前进。 包到达web服务器——》80端口回复数据——》防火墙(经过反向DNAT处理)——这样就好像是防火墙自己回复了那个来自外网的请求包。——》发送给计算机D。(这里要求把防火墙作为web到达internet的网关)
 现在,我们来考虑和web服务器在同一个内网(这里是指所有机子不需要经过路由器而可以直接互相访问的网络,不是把服务器和客户机又分在不同子网的情况)的C客户机访问它时会发生什么。我们假设客户机的IP为192.168.10.7,其他设置同上。

由于A是C的网关。C发送请求去往A——》A接到请求后包被DNAT后送往B——》但是包没有经过SNAT 的处理,所以包还是使用它自己的源地址,就是192.168.10.7(译者注:这就是IP 传输包的特点,只根据目的地的不同改变目的地址,但不因传输过程中要经过很多路由器而随着路由器改变其源地址,除非你单独进行源地址的改变。其实这一步的处理和对外来包的处理是一样的,只不过内网包的问题就在于此,所以这里交待一下原因)。 ——》包离开防火墙,到达web服务器。——》web服务器试图回复这个包。因为来自同一个网络的一台机子,它会把回复包直接发送到请求包的源地址也就是 192.168.10.7。——》回复包到达C客户机,但C它会很困惑,因为这个包不是来自它请求的那台防火墙。这样,它就会把这个包扔掉而去继续等待 “真正”的回复包。 这就是问题所在~~

针对这个问题有两个解决办法:

第一、

因为这些包都要进入防火墙,而且它们都去往需要做DNAT才能到达的那个地址,所以我们只要对这些包做SNAT操作即可。
比如,我们来考虑上面的例子,如果对那些进入防火墙而且是去往地址为web IP、端口为80的包做SNAT操作,那么这些包就好象是从LAN_IP来的了,也就是说,这些包的源地址被改为LAN_IP了。
这样,web服务器就会把回复包发给防火墙,而防火墙会再对包做 Un-DNAT操作,并把包发送到客户机。
解决问题的规则如下:

 iptables -t nat -A POSTROUTING -p tcp -d 192.168.10.8 --dport 80 -j SNAT --to-source 192.168.10.1

要记住,按运行的顺序POSTROUTING链是所有链中最后一个,因此包到达这条链时,已经被做过DNAT操作了,所以我们在规则里要基于内网的地址web_IP(包的目的地)来匹配包。
 警告:我们刚才写的这条规则会对日志产生很大影响,这种影响应该说是很不好的。因为来自 Internet包在防火墙内先后经过了DNAT和SNAT处理,才能到达web服务器(上面的例子),所以web服务器就认为包是防火墙发来的,而不知道真正的源头是其他的IP。这样,当它记录服务情况时,所有访问记录的源地址都是防火墙的IP而不是真正的访问源。
我们如果想根据这些记录来了解访问情况就不可能了。因此上面提供的“简单办法”并不是一个明智的选择,但它确实可以解决“能够访问”的问题,只是没有考虑到日志而已。
其他的服务也有类似的问题。比如,你在LAN内建立了SMTP服务器,那你就要设置防火墙以便能转发SMTP的数据流。这样你就创建了一个开放的SMTP中继服务器,随之而来的就是日志的问题了。 一定要注意,这里所说的问题是针对没有建立DMZ或类似结构的网络,并且内网的用户访问的是服务器的外网地址而言的。
(译者注:因为如果建立了DMZ,或者服务器和客户机又被分在不同的子网里,那就不需要这么麻烦了。因为所有访问的源头都不在服务器所在的网里,所以就没必要做SNAT去改变包的源地址了,从而记录也就不是问题了。如果内网客户是直接访问服务器的内网地址那就更没事了)

原创粉丝点击