Static NAT with iptables on Linux
本文的名字取的比较有意义,因为本文并不是真的要讨论如何在Linux上使用iptables实现static nat!之所以这么命名本文,是想引起别人的注意,因为中文资料,以及国内的搜索引擎,基本上没有人关注这个问题,也几乎没有什么人讨论这个问题,而我却由于项目原因以及平时的折腾,切身体会到了Linux的NAT实现的缺陷。如果你使用google,你会看到大量的国外的技术宅男宅女们在讨论这个问题,虽然也并没有给出一个明确的解答(但是我相信,解答很快就会有的,xtables-addons-2.4?or later...)!我希望,即使你问的是度娘,“Static NAT with iptables on Linux”也能给出一个答案!如果本文不幸被某位大牛看到,加之这哥们儿再有点影响力,那么搞出来一个真正的Static Stateless的NAT实现就指日可待了!
我相信,国内很多人也碰到了这个问题,也觉得Linux的NAT无法实现纯净的Static,Stateless,千万别扯RAWNAT,对于这个东西以及背后的想法,我可能比你知道的多些,RAWNAT不也得配两条规则吗?何况,即使你不把配置两条规则当成缺点-UNIX哲学笃信,能让人多个动作实现的,它绝不合并成一个,更加本质的原因在于Linux NAT规则的查找方式上。
Linux的NAT附着于ip_conntrack之上,我再说一遍。这是一个优点,可以在一个流内部,一次查找,多次使用。然而我们看看这个查找的方式与代价,它是顺序查找的,也就是按照用户配置的顺序遍历规则表,假设我们已近实现了可以用iptables配置的static NAT,那么在10000个地址需要转换的情况下,让你失望的效果是多么明显,以至于你马上就由于其不可扩展的缺陷而改用BSD或者直接购买Cisco了,幸运的是,这种事从来没有发生,因为这只是一个假设,真正的可以用iptables配置的static NAT还没有实现,也许你会说:
iptables -t nat ....-s 1.1.1.1 -j SANT --to-source 2.2.2.2
iptables -t nat ....-d 2.2.2.2 -j DANT --to-destination 1.1.1.1
这算什么?配置工作量直接扩大两倍,虽不经常,也不绝对,这两条规则配置在了最后,赶紧抱着你的UNIX哲学跳楼吧!
这么说吧,Linux没有实现一种可扩展的NAT规则查找机制,也许你会这么反驳我,Cisco的NAT不也有基于ACL的吗?ACL不也是按照配置顺序配置的吗?好吧,我承认你有点文化,并且带着怀疑论者的论调而不是妄下结论:“不,你错了!”。这实际上是我要说的话,并且很直接:不,你错了!首先基于ACL的匹配是针对于动态NAT的,它将匹配任务交给了ACL;其次,Cisco有自己的static NAT机制,在配置的时候就将映射注入系统,然后针对任意使能了NAT的接口进来的数据包执行统一高效的NAT表查询。
现在我们抽离出NAT的操作步骤,首先要决定哪些包需要NAT,其次是查找NAT规则以便知道如何NAT,最后就是执行NAT。以上第三步执行NAT想必都是一样的,改一下包头即可,重点在前两个步骤。
先看第一步,对于动态NAT,需要基于match来匹配,因为只有在符合一定条件的情况下,才能NAT,对于Linux,使用用户配置iptables NAT的顺序来匹配,对于Cisco,使用ACL,二者是一样的。然而针对static NAT,则这一点是确定的,在配置的时候就是确定的,然而Linux根本就没有实现,即使可以使用两条iptables实现,那也是使用用户的配置顺序来匹配的,这就不妥了,对于Cisco则没有这个问题。Cisco将高优先权匹配赋予了静态NAT,而Linux则全部依赖用户配置iptables规则的顺序。虽然依附于ip_conntrack的NAT可以提高效率,不必每次都遍历iptables NAT规则,但那也是在一个连接内部有效,起码对static的NAT不公平,试想大量的短连接的情况...
再看第二步,第一步知道了哪些包要NAT,现在来看如何NAT,对于Linux而言,这个步骤和第一个步骤是合在一起的,即在你知道了它要NAT的时候就同时知道如何来NAT,前者就是matches,后者是target,而对于Cisco-也是本应该的做法,动态NAT情况,ACL和ip nat pool是分来的,并且一旦知道了如何NAT,该条NAT映射就会被注入系统内部,后续的包就可以直接在系统中查找NAT映射了而不必每次都匹配ACL了,静态NAT情况,该步骤和第一步是合在一起的。Linux也不是每次都匹配iptables的NAT规则,而是将“如何NAT”的结果附着于ip_conntrack的反向五元组上,后面的包直接查ip_conntrack即可,而这个查询是快速的。
虽然我自己修改了一些代码已经可以应对这个问题,但是还是希望能有更加“官方”,更加健壮的代码出自业界大牛之手。另外令我费解的是,难道真的就没有碰到这个问题吗?肯定有人碰到过,虽然Linux作为纯网络设备的情况很少,但是对于中小型机构还是有的,宁可配置两条策略也不去想想怎么能一条搞定?好吧,我承认网上有很多封装,一条命令就能搞定,我在项目中也做过这种垃圾至极的封装,试问这些封装者,你们怎么也不去想想怎么去改进,问题被规避了而不是解决了。封装只是为了使用上的方便,但你一定要明白冰山下面有什么。我特别恶心那些介绍某种库的文字:xxx可以专注于业务逻辑,而不必xxx关注它的实现xxx。不关注并不代表不懂,不关注的意思是你不用自己去实现,但是你一定要理解为什么要这么实现!另外,并不是所有的事情都能靠封装解决的,Static NAT with iptables on Linux就是一例!
Static NAT with iptables on Linux的更多相关文章
- CentOS下配置iptables防火墙 linux NAT(iptables)配置
CentOS下配置防火墙 配置nat转发服务CentOS下配置iptables防火墙 linux NAT(iptables)配置 CentOS下配置iptables 1,vim /etc/syscon ...
- 使用NAT方式连网的linux服务器虚拟机搭建
从一开始我就很纠结centos服务器搭建的过程. 由于自己方向并不在运维上,但是学习开发也需要用到Linux所以就一直没认真去学. 经过自己多方面摸索与学习找到了自己的一套方法. 首先我用到的是 ce ...
- ebtables和iptables与linux bridge的交互
本文为翻译文,不一定是逐字逐句的翻译,而且中间会加上自己的一点见解,如有理解错误的地方,还请大家指出,我定虚心学习.原文见链接 其中斜体字是自己的理解,建议和ebtables手册和iptables手册 ...
- 【iptables】linux网络防火墙-iptables基础详解(重要)
一:前言 防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件的或者软件的防火墙两种.无论是在哪个网络中,防火墙工作的地方一定是在网络的边缘.而我们的任务就是需要去定义到底防 ...
- The Beginner’s Guide to iptables, the Linux Firewall
Iptables is an extremely flexible firewall utility built for Linux operating systems. Whether you’re ...
- Static, Shared Dynamic and Loadable Linux Libraries
转载:http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html Why libraries are used: Th ...
- linux平台下防火墙iptables原理(转)
原文地址:http://www.cnblogs.com/ggjucheng/archive/2012/08/19/2646466.html iptables简介 netfilter/iptables( ...
- Linux iptables 配置规则
Linux iptables 防火墙配置规则 前言:把网上我感觉不错iptables的访问规则都统一在这里,以后做参考. modprobe ipt_MASQUERADE modprobe ip_con ...
- Packet filtering with Linux & NAT
http://www.linuxfocus.org/ChineseGB/May2003/article289.shtml Gateway, Proxy-Arp 和 Ethernet Bridge ? ...
随机推荐
- asp.net中GridView的CheckedUnBindCheckBox属性
1. 获取GridView中CheckBox所选行的字段,即使是在绑定了数据源的时候,也可以获取选中的CheckedUnBindCheckBox对应的各个列的字段 使用时根据实际情况适当的修改即可. ...
- webstore+nodejs
新建一个普通的project. 编写如下代码: var http=require('http'); http.createServer(function(req,res){ res.writeHead ...
- html5 飞船动画
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- JSP个人总结
应用JSP技术开发动态网站 JSP基本语法 默认JSP: <%@ page language="java" contentType="text/html; char ...
- 结构体page_cur_t
/** Type of the index page */ typedef byte page_t; /** Index page cursor */ typedef struct page_cur_ ...
- 【转】下载太慢?简单设置让iTunes提速十几倍
原文网址:http://www.startos.com/mac/ipad/tips/2010120713291.html 今年可以说是苹果欢笑的一年,ipad的发布,iphone4的成功,让用苹果设备 ...
- [c#美味] Guid ToString 格式知多少?
在日常编程中,Guid是比较常用的,最常见的使用就是如下所示: string id = Guid.NewGuid().ToString(); 这条语句会生成一个新的Guid并转成字符串,如下: // ...
- LoadRunner脚本优化之—参数化迭代介
在LoadRunner的脚本优化时,有时发送给服务器的请求参数化时,服务器返回的内容也会和参数化的内容相对应,例如发送的请求带有查询key=123,则服务器也会返回含有123相关的内容.这时我们在使用 ...
- JZ2440开发笔记(5)——通过按键点亮LED
在JZ2440中,点亮LED就是给LED的控制位设置为输出,数据位设置为低电平,而通过按键点亮LED,就需要将按键对应的控制位设置为输出. 下面是JZ2440的3个LED电路图: 下面是JZ2440的 ...
- Oracle的dmp文件的导入
项目开始拿到了dmp文件,数据库用的是10g的,但是尽然没导成功,后来想可能导出的时候用11导出的,决定试一下. 正好自己的机器是11的客户端,结果不识别imp命令,到安装目录下的bin文件夹下看尽然 ...