关于linux中nat实现的一些思考

晨曦之光 发布于 2012/04/10 15:00
阅读 771
收藏 1

DNAT主要是用于保护nat内侧的服务器,针对外部主动连接内部的情形,而SNAT恰恰相反,为了保护和限制内部的网络客户机,针对的是内部主动连接外部的情形,在linux中,nat是基于连接跟踪模块起作用的,连接跟踪模块将每一个数据包试图和一个连接关联,结果就是要么这个数据包属于一个已经存在的连接,要么这个数据包不属于任何一个已经存在的连接,这种情况下连接跟踪模块将要为此数据包创建一个连接,显然该数据包是这个连接的第一个数据包。如果一个连接正好匹配一条nat规则,那么该规则将附着在表示这个连接的结构体上,在linux中就是ip_conntrack结构体,而这个nat的规则就处于该结构体内,表示为ip_nat_info,其中ip_nat_info_manip类型的数组表示了该连接每一个HOOK点的每一个方向的nat转换规则,我们知道linux中关于nat一共具有4个HOOK点,post-routing和local-in为snat点,而pre-routing和local-out为dnat点,同时如果一个连接命中了上述的hook点,那么相反方向的对称HOOK点自动命中,也就是说,如果在post-routing上执行snat,那么对于同一个连接,如果有数据进来,那么就要在pre-routing上执行dnat,因此ip_nat_info_manip类型的数组个数最多为6个,分别为为pre-routing<=>post-routing,local-in<=>local-out,local-out->post-routing,pre-routing->local-in,可以看出,每个HOOK点上是转换源地址还是转换目的地址是固定的,并不因为你是配置SNAT还是配置DNAT而有所改变,那为何还要区分snat和dnat呢?详情请看RFC,这里说一个显而易见的原因,因为nat的实现是基于连接的,那么就有谁发起这条连接的问题,如果nat中不分方向的话,也就是说设置了snat那么相反方向的dnat自动生效的话,就会导致很多无用的逻辑被执行,举个例子,外部网络有一个主机想连接内部网络,由于对内部网络配置的snat自动生效了外部访问内部的dnat,那么连接管理钩子发现这个连接之后会初始化一个新的连接结构体,然后交给nat钩子,由于发现了一条规则,于是进行地址转换,然后继续传给别的过滤钩子,一般情况下,内部客户主机是不允许被动连接的,因此很多这样的外部连接内部客户机的请求都会被防火墙拒绝,因此前面那个地址转换就没有任何意义,如果真的需要外部访问内部服务器,那么就专门配置一个dnat,而不能依赖snat的回应这种隐式的dnat。
     对于nat还有两个问题需要注意,第一个是内部客户机用公网ip访问内部服务器的情况,这时就需要在网关配置一个回环nat,也就是说在内网的接口对于进来的包且访问内网服务器的连接同时进行snat和dnat,snat将内网客户机的ip改为一个公网ip,dnat将公网的服务器ip改为内网服务器ip,返回的包做逆向操作,设置回环nat的原因在于如果不设置回环nat,那么客户机的请求还是可以到服务器的,但是服务器通过查看请求的源地址,发现是同一网段的,于是就会直接向客户机发送回复而不会发给网关,此时客户机收到服务器的直接回复之后就会因为源地址不对而丢弃该回复(服务器的源地址应该是一个公网的地址);第二个问题就是为何在local-in和local-out上会有nat的发生,这是专门为nat网关进程设置的,由于数据包从本地产生或者流向本地,那么对于本机流出的数据来讲,pre-routing其实就是local-out,而对于流向本机的数据,post-routing其实就是local-in,那么为何在pre/post-routing上安装nat钩子,这个问题的回答真的不是很容易,需要在路由,过滤,nat之间寻找平衡点,找平衡点的方法就是根据多条数据流向不同的连接,在{路由代价,过滤代价,nat代价}三元组中寻找代价最小的,对于出去的数据,路由和过滤完结后进行nat是一个很好的选择,对称的讲,dnat就要放在过滤和路由之前,然后snat的应答uu-snat也就是dnat的位置和原始dnat的位置重合是个最简化的设计,最后为了迎合非foward的数据包,出现了local-in和local-out两个与pre-routing和post-routing相对于foward对称的点,从拓扑上看,linux的nat就是一个马鞍面的设计,这种马鞍面没有极值点,但是拥有最平衡点。
    最后,虽然内核的netfilter提供了5个HOOK点,但是对于iptables实用工具来讲这5个HOOK点并不是可以随意组合的,比如filter就不能在pre-routing和post-routing上挂载钩子,只能在local-in,local-out,foward上挂载钩子,另外nat不能在post-routing上挂载dnat,这些限制也不是不可能截除,只是iptables提供了最佳的组合策略,其余的组合将是没有多大意义的,另外就是这样能使得配置防火墙和nat更加简单一些,一切配置标准完全依照iptables的建议进行,正如上面分析马鞍面式的nat一样,整个iptables的建议就是一个更大的马鞍面,而netfilter只是一个平面,iptables将它折成了马鞍面。


原文链接:http://blog.csdn.net/dog250/article/details/5482771
加载中
返回顶部
顶部