|
发表于 2007-1-17 15:15:06
|
显示全部楼层
以下内容抄自Iptables 指南 1.1.19
Oskar Andreasson
因为DNAT要做很多工作,所以我要再罗嗦一点。我们通过一个例子来大致理解一下它是如何工作的。比如,我想通过Internet连接发布我们的网站,但是HTTP server在我们的内网里,而且我们对外只有一个合法的IP,就是防火墙那个对外的IP——$INET_IP。防火墙还有一个内网的IP——$LAN_IP,HTTP server的IP是$HTTP_IP (这当然是内网的了)。为了完成我们的设想,要做的第一件事就是把下面的这个简单的规则加入到nat表的PREROUTING链中:
iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP
现在,所有从Internet来的、到防火墙的80端口去的包都会被转发(或称做被DNAT )到在内网的HTTP服务器上。如果你在Internet上试验一下,一切正常吧。再从内网里试验一下,完全不能用吧。这其实是路由的问题。下面我们来好好分析这个问题。为了容易阅读,我们把在外网上访问我们服务器的那台机子的IP地址记为$EXT_BOX。
1.
包从地址为$EXT_BOX的机子出发,去往地址为$INET_IP 的机子。
2.
包到达防火墙。
3.
防火墙DNAT(也就是转发)这个包,而且包会经过很多其他的链检验及处理。
4.
包离开防火墙向$HTTP_IP前进。
5.
包到达HTTP服务器,服务器就会通过防火墙给以回应,当然,这要求把防火墙作为HTTP到达$EXT_BOX的网关。一般情况下,防火墙就是HTTP服务器的缺省网关。
6.
防火墙再对返回包做Un-DNAT(就是照着DNAT的步骤反过来做一遍),这样就好像是防火墙自己回复了那个来自外网的请求包。
7.
返回包好象没经过这么复杂的处理、没事一样回到$EXT_BOX。
现在,我们来考虑和HTTP服务器在同一个内网(这里是指所有机子不需要经过路由器而可以直接互相访问的网络,不是那种把服务器和客户机又分在不同子网的情况)的客户访问它时会发生什么。我们假设客户机的IP为$LAN_BOX,其他设置同上。
1.
包离开$LAN_BOX,去往$INET_IP。
2.
包到达防火墙。
3.
包被DNAT,而且还会经过其他的处理。但是包没有经过SNAT 的处理,所以包还是使用它自己的源地址,就是$LAN_BOX(译者注:这就是IP 传输包的特点,只根据目的地的不同改变目的地址,但不因传输过程中要经过很多路由器而随着路由器改变其源地址,除非你单独进行源地址的改变。其实这一步的处理和对外来包的处理是一样的,只不过内网包的问题就在于此,所以这里交待一下原因)。
4.
包离开防火墙,到达HTTP服务器。
5.
HTTP服务器试图回复这个包。它在路由数据库中看到包是来自同一个网络的一台机子,因此它会把回复包直接发送到请求包的源地址(现在是回复包的目的地址),也就是$LAN_BOX。
6.
回复包到达客户机,但它会很困惑,因为这个包不是来自它访问的那台机子。这样,它就会把这个包扔掉而去等待“真正”的回复包。
针对这个问题有个简单的解决办法,因为这些包都要进入防火墙,而且它们都去往需要做DNAT才能到达的那个地址,所以我们只要对这些包做SNAT操作即可。比如,我们来考虑上面的例子,如果对那些进入防火墙而且是去往地址为$HTTP_IP、端口为80的包做SNAT操作,那么这些包就好象是从$LAN_IP来的了,也就是说,这些包的源地址被改为$LAN_IP了。这样,HTTP服务器就会把回复包发给防火墙,而防火墙会再对包做 Un-DNAT操作,并把包发送到客户机。解决问题的规则如下:
iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \ --to-source $LAN_IP
要记住,按运行的顺序POSTROUTING链是所有链中最后一个,因此包到达这条链时,已经被做过DNAT操作了,所以我们在规则里要基于内网的地址$HTTP_IP(包的目的地)来匹配包。 |
|