iptables的netfilter框架是基于会话的,因而理解起来和单包发送不同,和路由器的理解也不同。
参考中的文档是我刚看到的文档,我认为其配置是不太对的,其人对事情的理解是错误的、模糊的。
特在此写一下我的理解
拓扑
z-xp(1.1.1.3)--(1.1.1.1)iptables(2.2.2.1)---WebServer(2.2.2.2)
配置示例
iptables -F
iptables -t nat -F
以上清空对应类型的规则表
iptables -t nat -A PREROUTING -p tcp -d 1.1.1.1 --dport 80 -j DNAT --to 2.2.2.2:80
iptables -t nat -A POSTROUTING -p tcp -d 2.2.2.2 --dport 80 -j SNAT --to 2.2.2.1
正确的原理:
iptables查找路由,准备发送(POSTROUTING,路由后,SNAT),
发送时将这个会话(即目的地址是2.2.2.2:80的tcp会话)又做了新翻译,
翻译的方法是将其源地址改为2.2.2.1(端口未变),然后发出去。这个翻译就是后面加的一条SNAT规则,
将发到webserver的数据包SNAT
因而从WebServer看收到的数据包全都是来自于2.2.2.1,这样webServer可以直接回给2.2.2.1。
iptables设备收到回包,由于其是基于会话的,
因而将这个回包视为与原请求包相对应的回应报文(虽然做了2次翻译),在发回到z-xp之前,
从z-xp角度看,回应报文的源地址使用1.1.1.1,目的地址使用1.1.1.3。
抓包分析证明了这个理解,在webserver侧抓包,
发现收到的都是2.2.2.1发送的报文,并无来自外网IP的报文
参考:
http://www.haiyun.me/archives/iptables-dnat-public-ip.html
原文章:
Iptables实现公网IP DNAT/SNAT
发布时间:June 13, 2013 // 分类:Iptables // No Comments
Iptables实现NAT是最基本的功能,大部分家用路由都是基于其SNAT方式上网,使用Iptables实现外网DNAT也很简单,不过经常会出现不能正常NAT的现象。
以下命令将客户端访问1.1.1.1的HTTP数据DNAT到2.2.2.2,很多人往往只做这一步,然后测试不能正常连接。
1
|
iptables -t nat -A PREROUTING -p tcp -d 1.1.1.1 --dport 80 -j DNAT --to 2.2.2.2:80
|
想像一下此时客户端访问1.1.1.1的数据流程:
1
2
3
4
|
客户端访问1.1.1.1
1.1.1.1根据Iptables DNA将数据包发往2.2.2.2,此时源IP为客户端IP
2.2.2.2处理后根据源IP直接向客户端返回数据,要知道此时客户端是直接和1.1.1.1连接的
然后呢,客户端不知所云,不能正常连接
|
最后还要添加一条SNAT规则,将发到2.2.2.2的数据包SNAT,1.1.1.1充当代理服务器的角色。
1
|
iptables -t nat -A POSTROUTING -d 2.2.2.2 -j SNAT --to-
source
1.1.1.1
|
别忘记开启内核转发功能:
1
|
echo
1 >
/proc/sys/net/ipv4/ip_forward
|