免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1491 | 回复: 0
打印 上一主题 下一主题

[转载]- netfilter整体架构解析初步 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-02-01 18:55 |只看该作者 |倒序浏览

               
               
               
               
自己暂时还没有去看,直接从网上搜来参考:
------------------------------------ ZZ start ---------------------------------
netfilter整体架构解析初步  本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁用于任何商业用途。msn:
yfydz_no1@hotmail.com
来源:
http://yfydz.cublog.cn
1. 挂接点(hooknum) netfilter是Linux2.4/2.6内核中自带的防火墙架构,定义了5个挂接点:NF_IP_PRE_ROUTING-------->NF_IP_FORWARD--------->NF_IP_POST_ROUTING                     |                    ^                     |                    |                     V                    |                 NF_IP_LOCAL_IN       NF_IP_LOCAL_OUT netfilter定义了一个二维的链表头数组struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]来表示所有协议族的各个挂接点,NPROTO值为32,可表示linux所支持所有32个协议族(include/linux/socket.h文件中定义),也就是使用socket(2)函数的第一个参数的值,如互联网的TCP/IP协议族PF_INET(2)。每个协议族有NF_MAX_HOOKS(8)个挂接点,但实际只用了如上所述的5个,数组中每个元素表示一个协议族在一个挂接点的处理链表头,。 以下分析使用2.4.26内核中的netfilter代码。 在IPv4(PF_INET协议族)下,各挂接点定义在:[color="#0001FF"]NF_IP_PRE_ROUTING,在IP栈成功接收sk_buff包后处理,挂接点在在[color="#FF0102"]net/ipv4/ip_input.c的函数[color="#FF0102"]int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)中定义: return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,         ip_rcv_finish); [color="#0001FF"]NF_IP_LOCAL_IN,在对接收的sk_buff包完成路由分类判断是到达自身的包后进行处理,挂接点在在net/ipv4/ip_input.c的函数int ip_local_deliver(struct sk_buff *skb)中定义:  return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,         ip_local_deliver_finish); [color="#0001FF"]NF_IP_FORWARD,在对接收的sk_buff包完成路由分类判断是需要进行转发的包进行处理,挂接点在在net/ipv4/ip_input.c的函数int ip_forward(struct sk_buff *skb)中定义:  return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev2,         ip_forward_finish); [color="#0001FF"]NF_IP_LOCAL_OUT,在对自身发出的包进行处理,挂接点在在n[color="#FF0102"]et/ipv4/ip_output.c的函数int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,     u32 saddr, u32 daddr, struct ip_options *opt)中定义:  return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,         output_maybe_reroute);[color="#0001FF"]NF_IP_POST_ROUTING,在IP栈成功接收sk_buff包后处理,挂接点在在[color="#FF0102"]net/ipv4/ip_output.c的函数__inline__ int ip_finish_output(struct sk_buff *skb)中定义:  return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,         ip_finish_output2); 2. 挂接点操作 挂接点的操作由结构struct nf_hook_ops定义:include/linux/netfilter.hstruct nf_hook_ops{ struct list_head list; /* User fills in from here down. */ nf_hookfn *hook; int pf; int hooknum; /* Hooks are ordered in ascending priority. */ int priority;}; 数组中的元素说明如下:struct list_head list: 链表头,用于将此结构接入操作链表nf_hookfn *hook:用户定义的挂接处理函数int pf:协议族hooknum:挂接点priority:优先级 每个struct nf_hook_ops结构需要挂接到nf_hooks数组中的某个链表中才起作用,每个协议族的各种处理形成一个处理链表,链表上可以挂接多个节点,每个节点是一个数据处理结构(struct nf_hook_ops),用来描述对数据包进行如何处理,这些节点根据优先级顺序进行排序处理,优先级是有符号的32位数,值越小优先级越高,如果优先级相同,则按挂接的顺序依次处理,netfilter预定义了以下优先级:  NF_IP_PRI_FIRST = INT_MIN, NF_IP_PRI_CONNTRACK = -200, NF_IP_PRI_MANGLE = -150, NF_IP_PRI_NAT_DST = -100, NF_IP_PRI_FILTER = 0, NF_IP_PRI_NAT_SRC = 100, NF_IP_PRI_LAST = INT_MAX, 由此可见,netfilter的处理顺序是先连接跟踪、然后是mangle处理,再目的NAT(PREROUTING),然后是过滤(FILTER),然后是源NAT(POSTROUTING),这就是为什么mangle链的规则会先执行。 在各个处理点处理数据包时,如果发现需要丢弃数据包,那么数据包就被立即释放而不再进入后面的处理点;如果该处理点的最终结论是接受,那该数据包还会继续进入下一处理点进行匹配检查,所以对于最终通过防火墙的数据包,是经过了所有处理点的匹配的。3. 连接跟踪 连接跟踪的struct nf_hook_ops结构在net/ipv4/netfilter/ip_conntrack_standalone.c中定义,这是对用户隐藏的,也就是用户不能通过iptables规则对此操作点进行配置,是有系统自动完成的。 定义如下:static struct nf_hook_ops ip_conntrack_in_ops= { { NULL, NULL }, ip_conntrack_in, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_CONNTRACK };static struct nf_hook_ops ip_conntrack_local_out_ops= { { NULL, NULL }, ip_conntrack_local, PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_CONNTRACK }; 分别挂接在外部数据包进入(NF_IP_PRE_ROUTING)和自身数据发出(NF_IP_LOCAL_OUT)时进行处理,其功能就是判断该数据包是什么状态,填充该数据包struct sk_buff结构中struct nf_ct_info *nfct项的值,维护连接状态表,从而实现状态检测,具体处理过程分析可见另一篇文章:Linux下如何实现状态检测。 4. 规则表(table) 为了定义每个处理点上要执行哪些规则,netfilter定义了表(table)的概念,每个表由一个struct ipt_table来描述,如缺省的filter/nat/mangle表,每个表可单独分成几个规则链,分别在几个挂接点起作用,如filter表是在只在NF_IP_LOCAL_IN/NF_IP_LOCAL_OUT/NF_IP_FORWARD上起作用,然后通过函数ipt_do_table()来实现对某个表中某个hooknum的规则集进行匹配处理。而由结构struct nf_hook_ops所定义的各个处理点的处理函数都是直接或间接的调用了ipt_do_table()函数来实现对规则集的调用。 下面是系统缺省的三个表的定义情况:-------+---------------------------------+------------------------------------- table |  table definition               | file name-------+---------------------------------+-------------------------------------filter | struct ipt_table packet_filter  | net/ipv4/netfilter/iptable_filter.c       | hook   | NF_IP_LOCAL_IN、NF_IP_LOCAL_OUT、NF_IP_FORWARD       |ops    | struct nf_hook_ops ipt_ops[]       | net/ipv4/netfilter/iptable_filter.c       |       |NF_IP_LOCAL_IN: ipt_hook()       |    调用ipt_do_table()函数与filter表的INPUT链挂钩       |       |NF_IP_LOCAL_FORWARD: ipt_hook()       |    调用ipt_do_table()函数与filter表的FORWARD链挂钩       |       |NF_IP_LOCAL_OUT: ipt_local_out_hook()       |    调用ipt_do_table()函数与filter表的OUTPUT链挂钩       |-------+---------------------------------+-------------------------------------nat    | struct ipt_table nat_table      | net/ipv4/netfilter/ip_nat_rule.c       |                                 hook   | NF_IP_PRE_ROUTING_IN、NF_IP_LOCAL_OUT、NF_IP_POST_ROUTING       |ops    | net/ipv4/netfilter/ip_nat_standalone.c       |       |NF_IP_PRE_ROUTING:        |    struct nf_hook_ops ip_nat_in_ops, ip_nat_fn()       |      调用ip_nat_rule_find()函数       |        调用ipt_do_table()函数与nat表的PREROUTING链挂钩       |       |NF_IP_POST_ROUTING:        |    struct nf_hook_ops ip_nat_out_ops,ip_nat_out()       |      调用ip_nat_fn()       |        调用ip_nat_rule_find()函数       |          调用ipt_do_table()函数与nat表的POSTROUTING链挂钩       |-------+---------------------------------+-------------------------------------mangle | struct ipt_table packet_mangler | net/ipv4/netfilter/iptable_mangle.c       |                                 |hook   | 全部五个都有       |ops    | struct nf_hook_ops ipt_ops[]       | net/ipv4/netfilter/iptable_mangle.c       |       |NF_IP_PRE_ROUTING: ip_route_hook()       |    调用ipt_do_table()函数与mangle表的PREROUTING链挂钩       |       |NF_IP_LOCAL_IN: ip_route_hook()       |    调用ipt_do_table()函数与mangle表的INPUT链挂钩       |       |NF_IP_FORWARD: ipt_hook()       |    调用ipt_do_table()函数与mangle表的FORWARD链挂钩       |       |NF_IP_LOCAL_OUT: ipt_local_hook()       |    调用ipt_do_table()函数与mangle表的OUTPUT链挂钩       |       |NF_IP_POST_ROUTING: ip_route_hook()       |    调用ipt_do_table()函数与mangle表的POSTROUTING链挂钩       |-------+---------------------------------+------------------------------------- 每个数据处理表(table)中就是定义各自的规则集,是用动态长度的数组的形式保存,每个数组节点是一个规则,规则用struct ipt_entry结构进行描述,每条规则除了基本项外,其他附加匹配条件项还形成一个动态长度的匹配数组,struct ipt_entry中保存数组头的地址,每个匹配用结构struct ipt_match描述。规则的动作如果是扩展动作的话,用struct ipt_target描述。 用户可以自己定义自己的新的表,可以以缺省表为蓝本,然后定义新的struct nf_hook_ops操作节点,在该操作节点中调用ipt_do_table()函数将该ops和新表联系起来,这样就可以用iptables定义新的规则集。如果不定义新表,用户也可以在ops处理函数中对包直接进行判断处理,适合需要对包进行固定方式处理的场合。 5. 总结 netfilter架构以nf_hooks数组为基点,挂接在内核的协议处理的几个基本点上,通过链表方式链接struct nf_hook_ops处理结构,这些处理结构可以是在内核内部自动固定处理,如状态检测;也可以通过和struct ipt_table联系,通过iptables来动态配置处理规则,实现了一个扩展性很高的防火墙处理架构,不过实现细节部分仍然很复杂,各种细节功能将在后续文章里分析。
------------------------------------ ZZ,end ----------------------------------------------

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/111146/showart_2166794.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP