Linux网络防火墙【4】 Linux内核网络 iptables 之filter分析
2014-04-14 12:38
471 查看
对于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 */
下面是关于上面注册参数的代码。可以看到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 int
ipt_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 int
ipt_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规则的优化。
下面, 我以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_IN if (ret < 0) goto cleanup_table; ret = nf_register_hook(&ipt_ops[1]); //对应NF_IP_FORWARD if (ret < 0) goto cleanup_hook0; ret = nf_register_hook(&ipt_ops[2]); //对应NF_IP_LOCAL_OUT if (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 int
ipt_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 int
ipt_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规则的优化。
相关文章推荐
- netfilter/iptables 简介使用 netfilter/iptables 为 Linux(内核 2.4.x)配置防火墙
- 使用 netfilter/iptables 为 Linux(内核 2.4.x)配置防火墙
- 使用 netfilter/iptables 为 Linux(内核 2.4.x )配置防火墙
- Linux下Netfilter/IPtables防火墙案例分析
- Linux下Netfilter/IPTables防火墙案例分析
- netfilter/iptables 简介--使用 netfilter/iptables 为 Linux(内核 2.4.x)配置防火墙
- 【Linux 驱动】Netfilter/Iptables (七) 内核协议栈skb封装分析(续六)
- 洞悉linux下的Netfilter&iptables:内核中的ip_tables分析
- netfilter/iptables 为 Linux(内核 2.4.x)配置防火墙
- 科普一下Linux防火墙Netfilter/iptables
- 7-3 10 网络 防火墙 netfilter iptables
- (二)洞悉linux下的Netfilter&iptables:内核中的ip_tables小觑
- (十)洞悉linux下的Netfilter&iptables:网络地址转换原理之SNAT
- (二)洞悉linux下的Netfilter&iptables:内核中的ip_tables小觑
- Linux 防火墙:iptables基础-- filter表
- (八)洞悉linux下的Netfilter&iptables:状态防火墙
- Linux网络防火墙【1】 Linux内核网络netfilter 框架
- 二)洞悉linux下的Netfilter&iptables:内核中的ip_tables小觑
- (二)洞悉linux下的Netfilter&iptables:内核中的ip_tables小觑
- (十)洞悉linux下的Netfilter&iptables:网络地址转换原理之SNAT