netfilter框架概述

netfilter框架概述。

 

 

Netfilter从英文角度可以理解为,“网络数据过滤”,其实理解为“网络数据处”理更为贴切。

Netfilter框架之所以能实现许多强大的功能。

通俗的讲,是因为它在内核若干网络转发的关键函数中,设计了许多巧妙的钩子函数(钩子实际上是一个链表,钩子函数是链表上的结点),比如数据转发,由两个主要函数A和B函数实现,流程为A->B ,现在改变为A->钩子函数->B。

 

专业的讲,Netfilter框架为每种网络协议()定义一套HOOK函数。这些HOOK函数在数据报经过协议栈的几个关键点时被调用(NF_IP_PRE_ROUTING (0),NF_IP_LOCAL_IN (1),NF_IP_FORWARD (2),NF_IP_LOCAL_OUT (3),NF_IP_POST_ROUTING (4)),在这几个点中,协议栈将数据报及HOOK函数标号作为参数,传递给Netfilter框架。对于它在网络堆栈中增加的这些HOOK,内核的任何模块可以对每种协议的一个或多个HOOK进行注册,实现挂接。这样当某个数据报被传递给Netfilter框架时,内核能检测到是否有任何模块对该协议和HOOK函数进行了注册。若注册了,则调用该模块的注册时使用的回调函数,这样这些模块就有机会检查、修改、丢弃该数据报及指示Netfilter将该数据报传入用户空间的队列。这样,HOOK提供了一种方便的机制:在数据报通过Linux内核的不同位置上截获和操作处理数据报。

 

数据包进入ip协议栈后,以此进入这些函数,ip_rcv(),ip_local_deliver(),ip_forward(),ip_queue_xmit(),ip_finish_output()

 

五个HOOK。

NF_IP_PRE_ROUTING (0)

    数据报在进入路由代码被处理之前,数据报在IP数据报接收函数ip_rcv()(位于net/ipv4/ip_input.c,Line379)的最后,也就是在传入的数据报被处理之前经过这个HOOK。在ip_rcv()中挂接这个HOOK之前,进行的是一些与类型、长度、版本有关的检查。

    经过这个HOOK处理之后,数据报进入ip_rcv_finish()(位于net/ipv4/ip_input.c,Line306),进行查路由表的工作,并判断该数据报是发给本地机器还是进行转发。

    在这个HOOK上主要是对数据报作报头检测处理,以捕获异常情况。

         涉及功能(优先级顺序):Conntrack(-200)、mangle(-150)、DNAT(-100)

 

NF_IP_LOCAL_IN (1)

    目的地为本地主机的数据报在IP数据报本地投递函数ip_local_deliver()(位于net/ipv4/ip_input.c,Line290)的最后经过这个HOOK。

    经过这个HOOK处理之后,数据报进入ip_local_deliver_finish()(位于net/ipv4/ip_input.c,Line219)

    这样,IPTables模块就可以利用这个HOOK对应的INPUT规则链表来对数据报进行规则匹配的筛选了。防火墙一般建立在这个HOOK上。

         涉及功能:mangle(-150)、filter(0)、SNAT(100)、Conntrack(INT_MAX-1)

 

NF_IP_FORWARD (2)

    目的地非本地主机的数据报,包括被NAT修改过地址的数据报,都要在IP数据报转发函数ip_forward()(位于net/ipv4/ip_forward.c,Line73)的最后经过这个HOOK。

    经过这个HOOK处理之后,数据报进入ip_forward_finish()(位于net/ipv4/ip_forward.c,Line44)

    另外,在net/ipv4/ipmr.c中的ipmr_queue_xmit()函数(Line1119)最后也会经过这个HOOK。(ipmr为多播相关,估计是在需要通过路由转发多播数据时的处理)

    这样,IPTables模块就可以利用这个HOOK对应的FORWARD规则链表来对数据报进行规则匹配的筛选了。

         涉及功能:mangle(-150)、filter(0)

 

NF_IP_LOCAL_OUT (3)

    本地主机发出的数据报在IP数据报构建/发送函数ip_queue_xmit()(位于net/ipv4/ip_output.c,Line339)、以及ip_build_and_send_pkt()(位于net/ipv4/ip_output.c,Line122)的最后经过这个HOOK。(在数据报处理中,前者最为常用,后者用于那些不传输有效数据的SYN/ACK包)经过这个HOOK处理后,数据报进入ip_queue_xmit2()(位于net/ipv4/ip_output.c,Line281)

         另外,在ip_build_xmit_slow()(位于net/ipv4/ip_output.c,Line429)和ip_build_xmit()(位于net/ipv4/ip_output.c,Line638)中用于进行错误检测;在igmp_send_report()(位于net/ipv4/igmp.c,Line195)的最后也经过了这个HOOK,进行多播时相关的处理。

    这样,IPTables模块就可以利用这个HOOK对应的OUTPUT规则链表来对数据报进行规则匹配的筛选了。

         涉及功能:Conntrack(-200)、mangle(-150)、DNAT(-100)、filter(0)

 

NF_IP_POST_ROUTING (4)

    所有数据报,包括源地址为本地主机和非本地主机的,在通过网络设备离开本地主机之前,在IP数据报发送函数ip_finish_output()(位于net/ipv4/ip_output.c,Line184)的最后经过这个HOOK。

    经过这个HOOK处理后,数据报进入ip_finish_output2()(位于net/ipv4/ip_output.c,Line160)另外,在函数ip_mc_output()(位于net/ipv4/ip_output.c,Line195)中在克隆新的网络缓存skb时,也经过了这个HOOK进行处理。

         涉及功能:mangle(-150)、SNAT(100)、Conntrack(INT_MAX)

    其中,入口为net_rx_action()(位于net/core/dev.c,Line1602),作用是将数据报一个个地从CPU的输入队列中拿出,然后传递给协议处理例程。

    出口为dev_queue_xmit()(位于net/core/dev.c,Line1035),这个函数被高层协议的实例使用,以数据结构struct sk_buff *skb的形式在网络设备上发送数据报。

 

 

 

 

 

内核开发者可以根据这五个hook,编写自己的钩子函数,实现不同的功能。

根据pywj777的图,可以看出来,内核中的包重组,连接跟踪(当查看netstat时,tcp连接状态),NAT转发,包过滤等技术全部是由netfilter框架中定义的钩子函数实现的。因此根据功能目的,实现自己的钩子函数。

 

FAQ:

1,数据包是如何过钩子函数的?

比如数据包来到了nf_ip_pre_routing这个钩子,依次遍历钩子函数,如上图,从上至下遍历。

 

2,钩子函数是如何定义各自所在位置的?

钩子函数的数据结构是这个:

可以看出来,钩子函数位置是有其数据结构中的priority决定的,比如ipv4_conntrack_defrag的priority是-400(NF_IP_PRI_CONNTRACK_DEFRAG = -400,具体查看netfilter_ipv4.h)。

根据规定,遍历时是从最小值到最大值依次遍历 。

 

未完待续...

netfilter框架概述,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。