详解Linux下iptables中的DNAT与SNAT设置
DNAT(Destation Network Address Translation,目的地址转换) 通常被叫做目的映谢。而SNAT(Source Network Address Translation,源地址转换)通常被叫做源映谢。
这是我们在设置Lux网关或者防火墙时经常要用来的两种方式。以前对这两个都解释得不太清楚,现在我在这里解释一下。
,我们要了解一下IP包的结构,如下图所示
在任何一个IP数据包中,都会有Source IP Address与Destation IP Address这两个字段,数据包所经过的路由器也是根据这两个字段是判定数据包是由什么地方发过来的,它要将数据包发到什么地方去。而iptables的DNAT与SNAT就是根据这个原理,对Source IP Address与Destation IP Address进行修改。
然后,我们再看看数据包在iptables中要经过的链(cha)
图中正菱形的区域是对数据包进行判定转发的地方。在这里,系统会根据IP数据包中的destation ip address中的IP地址对数据包进行分发。如果destation ip adress是本机地址,数据将会被转交给INPUT链。如果不是本机地址,则交给FORWARD链检测。
这也就是说,我们要做的DNAT要在进入这个菱形转发区域之前,也就是在PREROUTING链中做,比如我们要把访问202.103.96.112的访问转发到192.168.0.112上
iptables -t nat -A PREROUTING -d 202.103.96.112 -j DNAT --to-destation 192.168.0.112
这个转换过程当中,其实就是将已经达到这台Lux网关(防火墙)上的数据包上的destation ip address从202.103.96.112修改为192.168.0.112然后交给系统路由进行转发。
而SNAT自然是要在数据包流出这台机器之前的一个链也就是POSTROUTING链来进行操作
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 58.20.51.66
这个语句就是告诉系统把即将要流出本机的数据的source ip address修改成为58.20.51.66。这样,数据包在达到目的机器以后,目的机器会将包返回到58.20.51.66也就是本机。如果不做这个操作,那么你的数据包在传递的过程中,reply的包肯定会丢失。
注意,DNAT target只能用在nat表的PREOUTING 和 OUTPUT 链中,或者是被这两条链调用的链里。但还要注意的是,包含DNAT target的连不能被除此之外的其他链调用,如POSTROUTING。
复制代码
Table 6-16. DNAT target
Option --to-destation
Example iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destation 192.168.1.1-192.168.1.10
Explanation指定要写入IP头的地址,这也是包要被转发到的地方。上面的例子就是把所有发往地址15.45.23.67的包都转发到一段LAN使用的私有地址中,即192.168.1.1到192.168.1.10。如前所述,在这种情况下,每个流都会被随机分配一个要转发到的地址,但同一个流总是使用同一个地址。我们也可以只指定一个IP地址作为参数,这样所有包都被转发到同一台机子。我们还可以在地址后指定一个或一个范围的端口。比如--to-destation 192.168.1.1:80或192.168.1.1:80-100。SNAT的语法和这个target的一样,只是目的不同罢了。要注意,只有先用--protocol指定了TCP或UDP协议,才能使用端口。
因为DNAT要做很多工作,所以我要再啰嗦一点。我们通过一个例子来大致理解一下它是如何工作的。比如,我想通过Inter连接发布我们的网站,HTTP server在我们的内网里,而且我们对外只有一个合法的IP,就是防火墙那个对外的IP——$INET_IP。防火墙还有一个内网的IP——$LAN_IP,HTTP server的IP是%HTTP_IP(这是内网的了)。为了完成我们的设想,要做的第一件事就是把下面这个简单的规则加入到nat表的PREROUTING链中
复制代码