Netfilter学习(1)

2084阅读 0评论2012-10-16 
分类:C/C++

   开始学习了Netfilter了,由于以前没有接触过该方面的知识,开始学习的比较吃力,于是从网上下载了份资料,比着前辈的思路慢慢学习,这样我想会比较快的了解Netfilter的,在这里非常感谢着位前辈,由于不知道您的尊姓大名,所以,再次表示感谢。

   学习Netfilter之前,先对着GFree_Wind的iptables的文章,对iptables有了一定的了解。链接地址如下所示http://blog.chinaunix.net/uid-23629988-id-85894.html

   凡是在这里记录的前辈的内容,我都会指出引用的,比如这一篇。

一、概述

   1、Netfilter/iptables是继2.0.x的IPchains之后,新一代的Linux防火墙机制。Netfilter采用模块化设计,具有良好的可扩展性。其重要工具模块iptables连接到Netfilter的架构中,并允许使用者对数据包进行过滤、地址转换和处理等等操作。

   Netfilter提供了一个框架,将对网络代码的直接干涉降到了最低,并允许用规定的接口将其他包处理代码以模块的形式添加到内核中,具有极强的灵活性。

   2、主要源代码文件
      ·Linux内核版本:2.4.21
      ·Netfilter主玩文件:net/core/netfilter.c
·Netfilter主头文件:include/linux/netfilter.h
      ·IPV4相关
·c文件:net/ipv4/netfilter/*c
·头文件:include/linux/netfilter_ipv4/*.h
  include/linux/netfilter_ipv4.h
      ·IPV4协议栈主体的部分c文件,特别是数据报传送过程有关的部分:
 ip_input.c , ip_forward.c , ip_output.c , ip_fragment.c等
  
    《以上确实给我扫盲了,谢谢》

二、Netfilter/iptables-ipv4总体架构

   Netfilter主要通过表、链实现规则,可以这么说,Netfilter是表的容器,表是链的容器,链式规则的容器,最终形成对数据报处理规则的实现。

   详细的说,Netfilter/iptables的体系结构可以分为三个大部分:
   
   1、Netfilter的Hook机制
   《这一部分是我非常感兴趣的》Netfilter的通用框架不依赖于具体的协议,而是为每种网络协议定义一套Hook函数。这些Hook函数在数据报经过协议栈的几个关键点时被调用,在这几个点中,协议栈将数据报以及Hook函数标号作为参数,传递给Netfilter框架。

   对于它在网络堆栈中增加的这些Hook,内核的任何模块可以对每种协议的一个或多个Hook进行注册,实现挂接(我知道的如LVS)。的那这样当某个数据报被传递给Netfilter框架时,内涵能检测到是否有任何模块对该协议和Hook函数进行了注册。若注册了,则调用该模块的注册时使用的“回调”函数,这样这些模块就有机会检查、修改、丢弃该数据报及指示该数据报传入用户空间队列。

   这样,Hook提供了一种方便的机制:在数据报通过Linux内核的不同位置上截获和操作处理数据报。

   2、iptables基础模块

   iptables基础模块实现了三个表来筛选各种数据报,具体的讲,Linux2.4内核提供了这三种数据报的处理功能是相互间独立的模块,都基于Netfilter的Hook函数和各种表、链实现的。这三个表包括:filter表、nat表以及mangle表。

   3、具体功能模块

   1> 数据报过滤模块
   2> 网络地址转换模块(NAT)
   3> 连接跟踪模块
   4> 数据报修改模块(mangle)
   5> 其他高级功能模块

   于是,Netfilter/iptables总体架构如果2-1所示。
图2-1 Netfilter/iptables的总体框架

三、Hook的实现

1、Netfilter-ipv4中的Hook

   Netfilter模块需要使用Hook来启动函数的动态钩接,它在IPV4中定义了五个Hook(位于文件include/linux/netfilter_ipv4.h, Line39),分别对应0-4个hooksum。

  1. /* IP Hooks */
  2. /* After promisc drops, checksum checks. */
  3. #define NF_IP_PRE_ROUTING    0
  4. /* If the packet is destined for this box. */
  5. #define NF_IP_LOCAL_IN        1
  6. /* If the packet is destined for another interface. */
  7. #define NF_IP_FORWARD        2
  8. /* Packets coming from a local process. */
  9. #define NF_IP_LOCAL_OUT        3
  10. /* Packets about to hit the wire. */
  11. #define NF_IP_POST_ROUTING    4
  12. #define NF_IP_NUMHOOKS        5
   简单的说,数据报经过各个Hook的流程如下:

   1> 数据报从进入系统,进行IP校验以后,首先经过第一个Hook点NF_IP_PRE_ROUTING进行处理;
   2> 然后进入路由代码,其决定该数据报是需要转发还是发给本地主机的。若该数据报是发给本机的,则该数据报经过Hook点NF_IP_LOCAL_IN处理以后,然后传递给上层协议;若该数据报是应该被转发的,则它被NF_IP_FORWARD处理,经过转发的数据报经过最后一个Hook点NF_IP_POST_ROUTING处理,再传到网络上;
   3> 本地产生的数据经过Hook点NF_IP_LOCAL_OUT处理后,进行路由选择处理,然后经过NF_IP_POST_ROUTING处理发送出去;

   总之,这五个Hook所组成的Netfilter-ipv4数据报筛选体系,如图3-1所示。
图3-1 Netfilter-ipv4数据报筛选体系

   详细的说,各个Hook及其IP数据报传递中的具体位置,如图3-2所示。
图3-2 Netfilter-ipv4数据报筛选体系(详细)

   * NF_IP_PRE_ROUTING(0)
   
   数据报在进入路由代码处理之前,数据报在IP数据报接受函数ip_rcv()(位于net/ipv4/ip_input.c)的最后,也就是在传入的数据报被处理之前经过这个Hook。在ip_rcv()中挂接这个Hook之前,进行的是一些与类型、长度、版本有关的检查。
   
   经过这个Hook处理之后,数据报进入ip_rcv_finish()(位于net/ipv4/ip_input.c),进行查路由表的工作,并判断该数据报是发给本地记起的还是进行转发的。
  
   在这个Hook上主要是对数据报作报文头检查工作处理,以捕获异常情况。

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

   * NF_IP_LOCAL_IN(1)

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

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

   这样,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)的最后经过这个Hook。

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

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

   这样,iptables模块就可以利用这个Hook对于的Forward规则链表来对数据报进行规则匹配的筛选了。

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

   * NF_IP_LOCAL_OUT(3)

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

   经过这个Hook处理后,数据报就进入了ip_queue_xmit2()(net/ipv4/ip_output.c)中用于进行错误检测;在igmp_send_report()(位于net/ipv4/igmp.c)的最后也经过这个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)的最后经过这个HOOK。

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

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


   其中,入口为net_rx_action()(位于net/core/dev.c),作用是将数据报一个个地从CPU接收队列中拿出,然后传递给协议处理历程。
         出口为dev_queue_xmit()(位于net/core/dev.c),这个函数被高层协议的实例使用,以数据结构strcut sk_buff *skb的形式在网络设备上发送数据报。





   备注:
   1、感谢我所看文档的作者,谢谢您讲的如此详细,若得知您的大名,定给出引用;
   2、感谢GFree_Wind,您的文章给我很多启示;


                    梦醒潇湘
    2012/10/16 16:44



上一篇:跟我一起学Load Balance(4)
下一篇:Linux下进程间通信