Linux网络防火墙【4】 Linux内核网络 iptables 之filter分析

来源:互联网 发布:淘宝好评评语怎么删除 编辑:程序博客网 时间:2024/05/21 13:58

对于iptables 而言, 其实 最核心的本质上就是注册在netfilter 链上的模块。不同版本的linux内核可能会有些不同,而且 现在linux 越来越复杂,比如filter封装的越来越多,3.20版本的filter 已经被封装了很多层,但是本质上 还是netfilter的module。

下面, 我以2.6.11版本的Linux 做一下简要的分析。 对于 更高版本的Linux 只要顺着 "找“, 最终还是会简化成 类似的思路。

iptable_filter.c

static int forward = NF_ACCEPT;     //默认的filter策略module_param(forward, bool, 0000);  //可以设置的内核参数。static int __init init(void){int ret;if (forward < 0 || forward > NF_MAX_VERDICT) {printk("iptables forward must be 0 or 1\n");return -EINVAL;}/* Entry 1 is the FORWARD hook */initial_table.entries[1].target.verdict = -forward - 1;/* Register table */ret = ipt_register_table(&packet_filter, &initial_table.repl);  //此处 注册了iptbles的表if (ret < 0)return ret;/* Register hooks */
/*filter因为有三个hook点,所以注册了三个netfilter module, 分别是local_in forward local_out*/ret = nf_register_hook(&ipt_ops[0]);    //此处才是真正注册了netfilter 模块,对应NF_IP_LOCAL_INif (ret < 0)goto cleanup_table;ret = nf_register_hook(&ipt_ops[1]);   //对应NF_IP_FORWARDif (ret < 0)goto cleanup_hook0;ret = nf_register_hook(&ipt_ops[2]);   //对应NF_IP_LOCAL_OUTif (ret < 0)goto cleanup_hook1;return ret; /*对应错误处理,一定要到位。内核的崩溃是最严重的错误*/ cleanup_hook1:nf_unregister_hook(&ipt_ops[1]); cleanup_hook0:nf_unregister_hook(&ipt_ops[0]); cleanup_table:ipt_unregister_table(&packet_filter);return ret;}static void __exit fini(void){unsigned int i;for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++)nf_unregister_hook(&ipt_ops[i]);ipt_unregister_table(&packet_filter);}module_init(init);module_exit(fini);

下面是关于上面注册参数的代码。可以看到ipt_ops[]对应上面代码的数组。 下面就是具体的结构体定义。

static struct nf_hook_ops ipt_ops[] = {{.hook= ipt_hook,    /*具体filter的入口,下同*/.owner= THIS_MODULE,.pf= PF_INET,            .hooknum= NF_IP_LOCAL_IN,   /*模块的hook点*/.priority= NF_IP_PRI_FILTER, /*优先级,对应filter raw nat等等的,按照不同的优先级进行处理*/},{.hook= ipt_hook,         //如上.owner= THIS_MODULE,.pf= PF_INET,.hooknum= NF_IP_FORWARD,.priority= NF_IP_PRI_FILTER,},{.hook= ipt_local_out_hook,  //如上.owner= THIS_MODULE,.pf= PF_INET,.hooknum= NF_IP_LOCAL_OUT,.priority= NF_IP_PRI_FILTER,},};

下面看看 hook函数。 主要 版本不一样, hook的形参 是不一样的,如何使用要根据具体的Linux版本来定义。

/* The work comes in here from netfilter.c. */static unsigned intipt_hook(unsigned int hook, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)){return ipt_do_table(pskb, hook, in, out, &packet_filter, NULL);}
可以看到 最终调用了ipt_do_table, 这是ipbtables规则处理的入口, 根据hook点 和 packet_fliter里面的iptables规则进行遍历,最终调用target。这里就不深入再去分析这个函数了,可以看到最终是 遍历对应的规则而已。


再看看locl_out的hook。

static unsigned intipt_local_out_hook(unsigned int hook,   struct sk_buff **pskb,   const struct net_device *in,   const struct net_device *out,   int (*okfn)(struct sk_buff *)){/* root is playing with raw sockets. */if ((*pskb)->len < sizeof(struct iphdr)    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {if (net_ratelimit())printk("ipt_hook: happy cracking.\n");return NF_ACCEPT;}return ipt_do_table(pskb, hook, in, out, &packet_filter, NULL);}

可以看到也是调用的ipt_do_table函数, 还是遍历规则。


从上面可以看到, 最终都是遍历了Iptables的规则。 所以Iptables的规则, 也是提高性能的切入点, 这可以说是 网络吞吐量的一个瓶颈。提高网络吞吐量,最终还是转换为对iptables规则的优化。






0 0
原创粉丝点击