从环回的iptables DNAT

我想了解使用iptables DNAT与回送地址的限制。 考虑我们有一个应用程序只能连接到127.0.0.1; 使服务器和客户端在不同的节点上工作的明显的解决scheme是使用NAT如下:

确保所有传出的数据包都具有主客户端主机的IP地址:

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source <CLIENT_IP> 

现在让我们试图欺骗客户和DNAT一个连接到外部世界:

 iptables -t nat -A OUTPUT -d 127.0.0.1/32 -p tcp -m tcp --dport <SERVICE_PORT> -j DNAT --to-destination <SERVER_IP> 

不幸的是,当试图连接到127.0.0.1:<SERVICE_PORT>时,这只是不起作用127.0.0.1:<SERVICE_PORT>程序只挂在connect syscall上。 有意思的是,我看不到任何接口上的任何SYN数据包( tcpdump -qn -i any port <SERVICE_PORT> ),但是我可以看到数据包计数器增加,同时查看iptables统计信息( iptables -nvL -t nat )。

search解决scheme我find了一个内核编译选项CONFIG_IP_NF_NAT_LOCAL ,它在内核2.6.0-2.6.10中使用来解决与本地发起的连接一起使用NAT的问题。 不幸的是,当前的git内核树拥有版本2.6.11和更高版本的信息,所以我在这里死路一条。

进一步看,我已经遇到了这个线程 ,关于一些DNAT在2.6.11环回问题的修复; 其中一个补丁删除CONFIG_IP_NF_NAT_LOCAL构build选项,并无条件地启用代码( 这里是实际的差异 )。

但是,这个问题的现状对我来说还是很不清楚的。 我想find一些解释或参考certificate这是一个内核错误或一些不是很好logging的function。 我知道networking127.0.0.0/8路由是由内核以一种特殊的方式处理的,但是从iptables文档中可以明显看出,nat table的OUTPUT链是唯一对这种规则有意义的地方,并且没有例外或任何有关127/8networking的注释。

请不要build议一些第三方工具的解决方法,我已经有一些,我只是想解释为什么这个确切的configuration不起作用,为什么它不应该工作。 任何有关如何使用任何其他iptables规则完成DNAT的例子都是受欢迎的。

上面的configuration在Debian挤压和wheezy上testing,内核2.6.32,3.1.0,3.2.0。

深入挖掘可以发现上述行为是完全正确的。

根据RFC 5735,networking127.0.0.0/8不应该路由在主机之外:

127.0.0.0/8 – 该块被分配用作互联网主机回送地址。 由更高级别的协议发送到该块内任何地址的数据报循环回到主机内部。 这通常只使用127.0.0.1/32进行环回。 如[RFC1122]第3.2.1.3节所述,整个127.0.0.0/8块中的地址不会合法地出现在任何地方的任何networking上。

RFC 1700 ,第5页也说明这些地址«不应该出现在主机之外»。

RFC 1812,第5.3.7节Martian地址过滤声明:«路由器不应该转发,除了通过回环接口,任何在networking127上有源地址的数据包»,这正是我的情况。

关于这些参考文献,我认为第一篇文章的案例确实是一个特征,而相反的行为则是违反标准。