IPTables概述
IPTables是基于Netfilter基本架构实现的一个可扩展的数据报高级管理系统或核外配置工具,利用table、chain、rule三级来存储数据报的各种规则。Netfilter-iptables由两部分组成,一部分是Netfilter的"钩子",另一部分则是知道这些钩子函数如何工作的一套规则--这些规则存储在被称为iptables的数据结构之中。钩子函数通过访问iptables来判断应该返回什么值给Netfilter框架。
系统预定义了三个table:
· filter:数据报过滤表(文件net/ipv4/netfilter/iptable_filter.c)
监听NF_IP_LOCAL_IN、NF_IP_FORWARD和NF_IP_LOCAL_OUT三个HOOK,作用是在所有数据报传递的关键点上对其进行过滤。
· nat:网络地址转换表
监听NF_IP_PRE_ROUTING、NF_IP_POST_ROUTING和NF_IP_LOCAL_OUT三个HOOK,作用是当新连接的第一个数据报经过时,在nat表中决定对其的转换操作;而后面的其它数据报都将根据第一个数据报的结果进行相同的转换处理。该模块以ConnectionTracking模块为基础,仅对每个连接的第一个报文进行匹配和处理,然后交由ConnectionTracking模块将处理结果应用到该连接之后的所有报文。nat仅对报文头的地址信息进行修改,而不修改报文内容,按所修改的部分,nat可分为源NAT(SNAT)和目的NAT(DNAT)两类,前者修改第一个报文的源地址部分,而后者则修改第一个报文的目的地址部分。SNAT可用来实现IP伪装,而DNAT则是透明代理的实现基础。
· mangle:数据报修改表(位于net/ipv4/netfilter/iptable_mangle.c)
监听NF_IP_PRE_ROUTING和NF_IP_LOCAL_OUT两个HOOK,作用是修改数据报报头中的一些值。
内核编程人员还可以通过注入模块,调用Netfilter的接口函数创建新的iptables。iptables功能强大,可以对核内的表进行操作,这些操作主要指对其中规则链的添加、修改、清除,由于iptables是操作核内Netfilter的用户界面,有时也把Netfilter-iptables简称为iptables。
IPTables的实现
1)表的实现
表的基本数据结构是ipt_table(位于include/linux/netfilter_ipv4/ip_tables.h,Line413):
struct ipt_table
{
struct list_head list; // 一个双向链表
char name[IPT_TABLE_MAXNAMELEN]; //被用户空间使用的表函数的名字
struct ipt_replace *table; //表初始化的模板,定义一个初始化用的
//该表的所默认的HOOK所包含的规则等信息,
// 用户通过系统调用进行表的替换时也要用
unsigned int valid_hooks; // 表所监听的HOOK,实质是一个位图
rwlock_t lock; // 整个表的读/写自旋锁
struct ipt_table_info *private; //表所存储的数据信息,也就是实际的数据区,
// 仅在处理ipt_table的代码内部使用
struct module *me; //如果是模块,那么取THIS_MODULE,否则取NULL
};
上文所提到的filter、nat和mangle表分别是ipt_table这个数据结构的三个实例:packet_filter(位于net/ipv4/netfilter/iptable_filter.c,Line84)、nat_table(位于net/ipv4/netfilter/ip_nat_rule.c,Line104)以及packet_mangler(位于net/ipv4/netfilter/iptable_mangle.c,Line117)。
……
2)规则的实现
一个完整的规则由三个数据结构共同实现,分别是:
a.一个ipt_entry结构,存储规则的整体信息;
b.0或多个ipt_entry_match结构,存放各种match,每个结构都可以存放任意的数据,这样也就拥有了良好的可扩展性;
c.1个ipt_entry_target结构,存放规则的target,类似的,每个结构也可以存放任意的数据。
……
IPTables的使用
通过使用iptables系统提供的特殊命令iptables建立这些规则,并将其添加到内核空间特定信息包过滤表内的链中。关于添加、去除、编辑规则的命令,一般脚本语法如下:
iptables [-t table] command [match][target]
1.表(table)
[-t table]选项允许使用标准表之外的任何表。表是包含仅处理特定类型信息包的规则和链的信息包过滤表。
2.命令(command)
command部分是iptables命令最重要的部分。它告诉iptables命令要做什么,例如插入规则、将规则添加到链的末尾或删除规则。表1是最常用的一些命令及例子。
表1 命令的功能和样例
3.匹配(match)
iptables命令的可选match部分指定信息包与规则匹配所应具有的特征(如源地址、目的地址、协议等)。匹配分为通用匹配和特定于协议的匹配两大类。这里将介绍可用于采用任何协议的信息包的通用匹配。表2是一些重要且常用的通用匹配及示例说明。
表2 通用匹配及示例说明
4.目标(target)
目标是由规则指定的操作,对与那些规则匹配的信息包执行这些操作。除了允许用户定义的目标之外,还有许多可用的目标选项。表3是常用的一些目标及示例说明。
除表3外,还有许多用于建立高级规则的其它目标,如LOG、REDIRECT、MARK、MIRROR和MASQUERADE等。
表3 目标及示例说明
Netfilter与iptables的关系
常听说Linux防火墙叫做“iptables”,其实这样的称呼并不是很正确,什么是iptables呢?在前面提过Netfilter所需要的规则是存放在内存中的,但问题是防火墙管理人员该如何将规则存放到内存呢?因此,防火墙管理人员会需要一个规则编辑工具,通过这个工具来对内存中的规则执行添加、删除及修改等操作,这个工具就是iptables以及ip6tables,其中iptables是在IPV4网络环境中使用,而ip6tables是在IPV6网络环境中使用,因此,Linux防火墙比较正确的名称应该是Netfilter/iptables。
此外,对于iptables结构上的问题我们必须加以了解,前面曾提到,Netfilter的模块越多,防火墙的功能也就越多,而且我们可以通过升级内核的方式来达到一起升级Netfilter的目的。不过,防火墙的升级不是仅仅升级内核就可以解决的,也并非一味增加Netfilter的模块,就可以无限扩充Netfilter的功能。我们要知道,防火墙管理人员是通过iptables工具,将“规则”写入到Netfilter的规则数据库(就是前面所提到的链)中,而这些规则有特定的“语法”,例如:“iptables-t filter -A INPUT -p tcp -m state --state ESTABLISHED, RELATED -jACCEPT ”,因此,当我们将规则传给iptables工具时,iptables工具会先检查语法是否正确,如果不正确,则iptables工具会显示语法错误的警告信息;反之,iptables就会把这些规则写入到规则数据库中。
事实上,不是只有Netfilter有模块,iptables工具也有模块,这些模块就存放在/lib/xTables目录下,该目录包含了iptables及ip6tables两个工具的模块。这些模块理应与Netfilter的模块是一一对应的,如/lib/modules/kernel_version/kernel/net/netfilter/目录中有一个模块称为xt_string.ko,在/lib/xTables/目录中就会有一个叫libxt_string.so的模块,也就是说,当我们下达与xt_string.ko相关的语法时,iptables工具会根据libxt_string.so模块的指示去检查语法是否正确,并将Netfilter的libxt_string.ko模块载入到系统内存中,iptables最后将规则写入到规则数据库中。
如果iptables工具没有包含下达规则中所需的模块,那么iptables会说你所下达的语法不正确,又如果iptables包含了我们所下达语法的模块,但Netfilter没有对应的模块可用,iptables会告诉我们某个Netfilter的模块不存在,因此,如果升级内核或Netfilter,iptables的软件也应随之升级才行。