iptables中DNAT与SNAT的理解

Linux , , , , , , , , ,

DNAT(Destination Network Address Translation,目的地址转换) 通常被叫做目的映谢。而SNAT(Source Network Address Translation,源地址转换)通常被叫做源映谢。

这是我们在设置Linux网关或者防火墙时经常要用来的两种方式。以前对这两个都解释得不太清楚,现在我在这里解释一下。

首先,我们要了解一下IP包的结构,如下图所示:
iphdr
在任何一个IP数据包中,都会有Source IP Address与Destination IP Address这两个字段,数据包所经过的路由器也是根据这两个字段是判定数据包是由什么地方发过来的,它要将数据包发到什么地方去。而iptables的DNAT与SNAT就是根据这个原理,对Source IP Address与Destination IP Address进行修改。

然后,我们再看看数据包在iptables中要经过的链(chain):
netfilter_packet_flow
图中正菱形的区域是对数据包进行判定转发的地方。在这里,系统会根据IP数据包中的destination ip address中的IP地址对数据包进行分发。如果destination 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-destination 192.168.0.112

这个转换过程当中,其实就是将已经达到这台Linux网关(防火墙)上的数据包上的destination 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的包肯定会丢失。


14 Responses to “iptables中DNAT与SNAT的理解”

  1. sealinger — April 8, 2009 @ 10:25 pm

    老兄,讲的太好了!深入浅出,受益匪浅!

  2. linux fan — April 15, 2009 @ 4:23 pm

    能否同时对源与目标都进行转换

    • myhnet — April 15, 2009 @ 4:26 pm

      同时?
      看明白这个图之后,就没有所谓的同时。
      在prerouting链里面做不了SNAT,postrouting链里面做不了DNAT
      做了也没有用

  3. mylinux — May 15, 2009 @ 1:49 am

    你说的好像都是包出去的时候iptables做的动作 能给分析包进来的时候包做的动作吗
    好象包回来的时候 prerouting和postrouting位置换了吧?请教!

  4. mylinux — May 15, 2009 @ 1:54 am

    最好举个例子说明一下包出去和回来的地址变化情况
    非常感谢

  5. myhnet — May 15, 2009 @ 9:12 am

    当一个数据包进入linux系统以后,首先进入mangle表的prerouting链,进行某些预路由的修改(也可能不改),然后数据包进入nat表的 prerouting链,进行dnat之类(改变数据包的目的地址,比如我们所说的网关,比如从外网返回的数据包并不知道是内网的哪台机器需要这个数据包,都发给了网关的外网地址,而网关就要把这些数据包的目的地址改为正确的目的地址,而不是自己)的事情,然后进行判断这个数据包是发给这台计算机自身的还是仅仅需要转发的。如果是转发,就发送给mangle表的FORWARD链,进行一些参数修改(比如tos什么的参数)或者不修改,然后送给 filter表的forward链进行过滤(就是通常所说的转发过滤规则),然后送给mangle表的postrouting链进行进一步的参数修改(或者不修改),然后发给nat表的postrouting链修改(或者不修改)源地址(比如网关这个时候会把本来发自内网ip的数据包的源地址改为自己的外网IP,这样发送出去后,外面的主机就会以为这是网关发出的数据包了),然后发给网卡设备发送到网上。

  6. geraint — September 15, 2009 @ 11:08 pm

    静态地址映射怎么回事?能解释下吗?

  7. jianghao — October 18, 2009 @ 10:00 pm

    input —对进入本机的数据进行过滤
    output —-对从本机出去的数据进行处理
    forward—– 对本网段的数据进行处理
    prerouting —— dnat 和 ports redirect
    postrouting ——-snat 和 masquerade

    iptables 其实 只有两条chains 是对本机有用的 input 和 output
    而 forwad 其实是用来处理局域网中的数据包的(因为linux一般是用来充当网关或者是路由器的)

    而 prerouting 和 postrouting 属于nat 表,这个 —其实是iptables的附加功能,主要是用来做翻译的,

    right???

  8. 祥哥哥 — April 19, 2010 @ 2:17 pm

    博主的文章 很不错。 可否交个友情链接。 贵站链接也做好

  9. ferity — June 2, 2010 @ 4:30 pm

    谢谢博主咯“` ^_^ 让我多了解了一些东西`

  10. iptables advance tips — September 2, 2010 @ 1:20 pm

    learn!

Leave a Reply