Linux网络虚拟化之iptables原理

        iptables除了用于设置防火墙、统计网络流量外,在Linux的网络虚拟化中也扮演着非常重要的角色,很多三层功能都与其有关。文中的IP数据报都特指IPv4。着重理解IP数据报在网络内核中的处理过程,以及Netfilter提供的五个挂载点,还有iptables的四表五链。

1.概述

        IP数据报在操作系统的内核网络栈中的处理,是通过调用一系列内核空间的函数实现的。普通用户可利用iptables添加规则(rule),而这些规则最终会映射成某些内核空间的函数,并挂接在IP数据报处理流程中的某个点上,从而实现对IP数据报的自定义处理,比如NAT、防火墙等。

        另外一点很重要,iptables能够识别出IP数据报是用于创建TCP链接的,还是用于释放TCP链接的,从而实现对TCP链接状态的监控。例如在实现端口多路复用的NAT功能时,会实现内网IP地址+端口号与外网IP地址+端口号的映射,那么这种映射关系什么时候创建?又是什么时候释放的呢?很显然,当iptables监控到链接创建时就实现映射,当监控到链接释放或者长时间没有数据传递时就释放映射。

2.IP数据报的处理流向及挂载点

        要理解Iptables就要先明白IP数据报在内核空间中的处理路径,以及用户可以在处理路径的那些点上挂载回调函数。下图1为IP数据报的处理路径及挂载点。额外说明的是这些挂载点是由Linux内核中的Netfilter提供的,Netfilter是内核网络模块中的一个子模块,用户通过这个模块提供的函数,实现自定回调函数的挂载解挂等操作。下图非常重要,特别是挂载点的位置。

Linux网络虚拟化之iptables原理_第1张图片

                                                                           图1

        上图是经过简化的流程图,略去了与本文所讨论主题无关的处理节点及分支。图中方框内黑色字体的,是Linux内核空间提供的函数,用来实现TCP/IP协议栈,必不可少。用户可通过修改内核参数来影响这些函数的行为,本文不涉及此主题,只所以在上图上画出是为了更清楚的说明挂载点的位置。

        图中的绿色箭头,表示从来自与外部网络,经过路由选择子系统确认后,终点是本主机的数据包流向。共经过两个挂载点,路由选择子系统之前的NF_INET_PRE_ROUTING与之后的NF_INET_LOCAL_IN。

        默认情况下,路由选择子系统发现数据包终点并不是本机时,就丢弃数据锯。但是当操作系统数据包转发功能打开时,如果数据包不是发往本地的,并不会被丢弃,而是由路由选择子系统确认是否为需要转发的数据包。如果也不能转发才丢弃。图中橙色箭头表示转发数据包的流向,完整的流向包含绿色箭头一部分、橙色全部、蓝色一部分。可以看出总共经过三个挂载点,路由选择子系统之前的NF_INET_PRE_ROUTING及之后的NF_INET_FORWARD、NF_INET_POST_ROUTING。

     蓝色箭头表示,数据包由本地发出,目的地是外部网络。共经过两个挂载点,分别是NF_INET_LOCAL_OUT、NF_INET_POST_ROUTING。

     综合起来,上图中一共出现了五个挂载点,分别是NF_INET_PRE_ROUTING、NF_INET_LOCAL_IN、NF_INET_FORWARD、NF_INET_LOCAL_OUT、NF_INET_POST_ROUTING。一定要明确记住这三种数据流向所经过的挂载点,以及在同一条流向中,挂载点的先后顺序。

3.iptables内核数据管理

        iptables也由两部分组成。我们平时调用的iptables命令是用户空间进程,iptables的数据管理在内核中。那么iptables是如何管理组织数据的呢?概括起来就是四表五链,如下图2,引用自百度百科。

Linux网络虚拟化之iptables原理_第2张图片

                                                                                        图2

        上图中总共有四个表,分别是raw、mangle、nat、filter。每个表中有数量不等的链,每个链中有规则。首先说明一下链,链是一种常见的数据结构,上图中总共出现了五种类型的链,分别是PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。那么为什么是五种类型的链而不是八种呢,每种链又是什么意思呢?请大家看图1,有几种挂载点?五种,好巧啊!答案就是链的类型与挂载点存在着一一对应的关系,对应关系如下表:

链类型

挂载点
PREROUTING NF_INET_PRE_ROUTING
INPUT NF_INET_LOCAL_IN
FORWARD NF_INET_FORWARD
OUTPUT NF_INET_LOCAL_OUT
POSTROUTING NF_INET_POST_ROUTING

iptables会调用Netfilter提供的函数,按照从raw到filter表的顺序,将相同类型链对应的回调函数依次挂载到与链类型对应的挂载点上。这也就解释了为什么有五种类型的链。

        那么为什么有四个表呢?这一点很好解释,我们在写代码的时候,总是把实现某一类功能的代码放在一个模块中。iptables也是如此,它分了四个表,单个表中的链实用于实现单个目的。先说一下四个表的优先级raw>mongle>nat>filter,这一点也很重要,raw表的优先级最高,其中的链、规则最先被挂载,也最先起作用,经过raw表处理的数据包,iptables将不跟踪统计它所属的链接状态,并且会直接跳过nat表,主要是为了提高效率。iptables主要是解析IP数据报的报头,但是mongle表中的规则侧重于处理IP数据报的数据部分,这个功能很少用。其它的两个就简单了filter表用于过滤,nat表用于网络地址转换。

        至此,iptables的原理就解释清楚了。


你可能感兴趣的:(Linux网络虚拟化)