通过netfilter的笔记2的例子,我们知道了怎么使用netfilter的框架,对于内核的设计原则来说,策略和机制分离,所以提供了iptables来供用户配置防火墙策略。
那么,怎么使用iptables呢?由于iptables的资料很多,本文将汇集一些,作为自己的学习过程记录。
netfiler内置了一些表,来管理iptables工具下发的规则,规则的保存是这样的:
可以这么说,Netfilter管理多张表,表管理多条链,链管理规则。简单地讲, tables 由 chains 组成,而 chains 又由 rules 组成。 iptables 默认有四个表 Filter, NAT, Mangle, Raw 。
这里只描述ipv4的,v6的和其他协议的类似,在配置中搜索的话,可以看到其他tables:
[root@Discovery ~]# grep CONFIG_NF_TABLES /boot/config-3.10.-.*
/boot/config-3.10.-862.6..el7.x86_64:CONFIG_NF_TABLES=m
/boot/config-3.10.-862.6..el7.x86_64:CONFIG_NF_TABLES_INET=m
/boot/config-3.10.-862.6..el7.x86_64:CONFIG_NF_TABLES_IPV4=m
/boot/config-3.10.-862.6..el7.x86_64:CONFIG_NF_TABLES_ARP=m
/boot/config-3.10.-862.6..el7.x86_64:CONFIG_NF_TABLES_IPV6=m
/boot/config-3.10.-862.6..el7.x86_64:CONFIG_NF_TABLES_BRIDGE=m
需要注意的是,在支持net的命名空间之后,所有的描述都是针对某一个net来说的。
描述table的数据结构是:
/* Furniture shopping... */
struct xt_table {
struct list_head list; /* What hooks you will enter on */
unsigned int valid_hooks; /* Man behind the curtain... */
struct xt_table_info *private; /* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me; u_int8_t af; /* address/protocol family */
int priority; /* hook order */ /* A unique name... */
const char name[XT_TABLE_MAXNAMELEN];
};
filter表:定义在iptable_filter文件中,
#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
( << NF_INET_FORWARD) | \
( << NF_INET_LOCAL_OUT)) static const struct xt_table packet_filter = {
.name = "filter",
.valid_hooks = FILTER_VALID_HOOKS,
.me = THIS_MODULE,
.af = NFPROTO_IPV4,------------------v4的
.priority = NF_IP_PRI_FILTER,
};
NAT表,定义在iptable_nat.c文件。
static const struct xt_table nf_nat_ipv4_table = {
.name = "nat",
.valid_hooks = ( << NF_INET_PRE_ROUTING) |
( << NF_INET_POST_ROUTING) |
( << NF_INET_LOCAL_OUT) |
( << NF_INET_LOCAL_IN),
.me = THIS_MODULE,
.af = NFPROTO_IPV4,-------------v4的
};
mangle表:定义在iptables_mangle.c文件中。
#define MANGLE_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
(1 << NF_INET_LOCAL_IN) | \
(1 << NF_INET_FORWARD) | \
(1 << NF_INET_LOCAL_OUT) | \
(1 << NF_INET_POST_ROUTING)) static const struct xt_table packet_mangler = {
.name = "mangle",
.valid_hooks = MANGLE_VALID_HOOKS,
.me = THIS_MODULE,
.af = NFPROTO_IPV4,-------------针对ipv4的
.priority = NF_IP_PRI_MANGLE,
};
raw表,定义在iptable_raw.c文件中:
#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) static const struct xt_table packet_raw = {
.name = "raw",
.valid_hooks = RAW_VALID_HOOKS,
.me = THIS_MODULE,
.af = NFPROTO_IPV4,-----------------v4
.priority = NF_IP_PRI_RAW,
};
可以看出,这些表的优先级是不一样的,:
enum nf_ip_hook_priorities {
NF_IP_PRI_FIRST = INT_MIN,
NF_IP_PRI_CONNTRACK_DEFRAG = -,
NF_IP_PRI_RAW = -,
NF_IP_PRI_SELINUX_FIRST = -,
NF_IP_PRI_CONNTRACK = -,
NF_IP_PRI_MANGLE = -,
NF_IP_PRI_NAT_DST = -,
NF_IP_PRI_FILTER = ,
NF_IP_PRI_SECURITY = ,
NF_IP_PRI_NAT_SRC = ,
NF_IP_PRI_SELINUX_LAST = ,
NF_IP_PRI_CONNTRACK_HELPER = ,
NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
NF_IP_PRI_LAST = INT_MAX,
};
总体上看,优先级顺序是:raw —> mangle —> nat —> filter。值越小优先级越大,也就是说在某一个链上有多张表,从chain的角度来说,相同的chain决定了hooknum是一样的,然后和pf一起决定了nf_hooks[reg->pf][reg->hooknum]中的位置,所以看出,表只是容器,起作用的还是chain,那么chain中的rule是如何生效的呢?