netfilter Linux 防火墙在内核中的实现_第1页
netfilter Linux 防火墙在内核中的实现_第2页
netfilter Linux 防火墙在内核中的实现_第3页
netfilter Linux 防火墙在内核中的实现_第4页
netfilter Linux 防火墙在内核中的实现_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、netfilter: Linux 防火墙在内核中的实现    netfilter: Linux 防火墙在内核中的实现                                     

2、               文档选项                                  &#

3、160;                                                 &#

4、160;                            将此页作为电子邮件发送                    &#

5、160;                                            未显示需要 JavaScript 的文档选项  

6、60;                                                 

7、60;                        级别: 初级    赵蔚 (zhaoway), Linux/Free Software 独立技术顾问    2002 年 12 月 01 日    本文介绍 Linux 的防火墙技术 netfil

8、ter/iptables 在 Linux 内核中的具体实现。    netfilter 和 Linux 防火墙介绍    Linux 的防火墙技术经历了若干代的沿革,一步步的发展而来。最开始的 ipfwadm 是 Alan Cox 在 Linux kernel 发展的初期,从 FreeBSD 的内核代码中移植过来的。后来经历了 ipchains,再经由 Paul Russell 在 Linux kernel 2.3 系列的开发过程中发展了 netfilter 这个架构。而用户空间的防火墙管理工具,也相应的发展为 i

9、filter/iptables 这个组合目前相当的令人满意。在经历了 Linux kernel 2.4 和 2.5 的发展以后,的确可以说,netfilter/iptables 经受住了大量用户广泛使用的考验。    本文并不打算介绍 Linux 防火墙在用户空间的管理程序 iptables 的使用。至于如何利用 netfilter/iptables 机制搭建一个可靠的 Internet 防火墙,这也不是本文感兴趣的话题。关于 iptables 的使用,读者朋友们可以参考 man iptables 的手册,也可以参考 netfilt

10、er 的核心开发者 Paul Russell 写的 Packet Filtering HOW-TO 和 NAT HOW-TO。相关的链接,请参见文后所列的参考资料目录。读者朋友们在阅读本文之前,最好能够对 iptables 的使用有一定的了解。    本文介绍 netfilter 在 Linux kernel 中的实现。如果条件允许的话,我们可能在后续的文章中将要进一步说明如何编写自己的 kernel modules 并将其镶嵌在 netfilter 的架构中,以实现自己的定制防火墙功能。值得指出的是,在 netfilter 的网站上,可以看到 netf

11、ilter 的一个子项目 patch-o-matic,其中收录了大量的各种定制 kernel modules,这些 modules 给读者朋友们开发自己的 kernel modules,提供了非常多的、很好的例子。                                &

12、#160;                            回页首                     

13、60;          IPv4 代码中 netfilter 的接口    netfilter 在 Linux kernel 中的 IPv4、IPv6 和 DECnet 等网络协议栈中都有相应的实现。本文限于篇幅,将只介绍其中最让大多数读者朋友们感兴趣的 IPv4 协议栈上的 netfilter 的实现。    我们在编译 Linux kernel 的过程中一定会注意到,netfilter 是一个在编译过程中可选的

14、部件。也就是说,用户在编译内核的过程中,可以按照自己的需要,决定是否要在自己的内核中编译进去 netfilter 的 kernel 支持。这就带给我们一个提示,实现 netfilter 的代码对于实现 IPv4 协议栈的代码的影响应该会是尽量的小,不那么引人注目才对。否则的话,IPv4 协议栈的代码维护工作就不得不和实现 netfilter 的代码的维护工作搅在一起,让人头疼了。    事实也的确如此,IPv4 协议栈为了实现对 netfilter 架构的支持,在 IP packet 在 IPv4 协议栈上的游历路线之中,仔细选择了五个参考点。在这五个参

15、考点上,各引入了一行对 NF_HOOK() 宏函数的一个相应的调用。这五个参考点被分别命名为 PREROUTING,LOCAL-IN,FORWARD,LOCAL-OUT 和 POSTROUTING。关于这五个参考点的含义,在 iptables 的使用说明中有准确的叙述,相信读者朋友们都应该了解了。从如下的 grep 输出,我们可以看到 IPv4 协议栈实现代码对 NF_HOOK() 宏函数的调用:                 zha

16、owayqhq /linux-2.4.19/net/ipv4 $ grep -n NF_HOOK *.c     arp.c:591:NF_HOOK(NF_ARP, NF_ARP_OUT, skb, NULL, dev, dev_queue_xmit);     arp.c:871:return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);     igmp.c:187:/* Dont just hand N

17、F_HOOK skb->dst->output, in case netfilter hook     igmp.c:252:return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,     ip_forward.c:145:return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev2,     ip_gre.c:668:

18、/* Need this wrapper because NF_HOOK takes the function address */     ip_input.c:302:return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,     ip_input.c:437:return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,     ip_outpu

19、t.c:111:/* Dont just hand NF_HOOK skb->dst->output, in case netfilter hook     ip_output.c:156:return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,     ip_output.c:191:return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, 

20、0;   ip_output.c:233:NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,     ip_output.c:249:NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,     ip_output.c:400:return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,   

21、  ip_output.c:603:err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,     ip_output.c:714:err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,     ipip.c:516:/* Need this wrapper because NF_HOOK takes the function address */  

22、0;  ipmr.c:1211:NF_HOOK(PF_INET, NF_IP_FORWARD, skb2, skb->dev, dev,     zhaowayqhq /linux-2.4.19/net/ipv4 $                     NF_HOOK() 这个宏函数,定义在 linux-2.4.19/include/li

23、nux/netfilter.h 里面。当 #ifdef CONFIG_NETFILTER 被定义的时候,就转去调用 nf_hook_slow() 函数;如果 CONFIG_NETFILTER 没有被定义,则从 netfilter 模块转回到 IPv4 协议栈,继续往下处理。这样就给了用户在编译 kernel 的时候一个选项,可以通过定义 CONFIG_NETFILTER 与否来决定是否把 netfilter 支持代码编译进内核。从这个函数的名称,我们也可以猜到,可以把 IPv4 协议栈上的这五个参考点,形象的看成是五个钩子。IP packet 在 IPv4 协议栈上游历的时候,途经这五个钩子,

24、就会被 netfilter 模块钓上来,审查一番,并据审查的结果,决定 packet 的下一步命运:是被原封不动的放回 IPv4 协议栈,继续游历;还是经过一些修改,再放回去;还是干脆丢弃掉算了?                                 

25、0;                           回页首                       

26、         netfilter 的核心模块    “鱼钩”和“垂钓点”    IP packet 被 NF_HOOK() 从 IPv4 协议栈上钓出来以后,就进入 linux-2.4.19/net/core/netfilter.c 中的 nf_hook_slow() 函数进行处理。这个函数干的主要事情,就是根据 nf_hooks 数组,开始处理 packet。准确地说来,上一段讲到的 IPv4 协议栈上的五个参考点,并不

27、是“钓鱼的钩子”,而是“允许垂钓的地点”。换句话说,IPv4 协议栈上定义了五个“允许垂钓点”。在每一个“垂钓点”,都可以让 netfilter 放置一个“鱼钩”,把经过的 packet 钓上来。那么 netfiler 的“鱼钩”都放在什么地方?就放在 nf_hooks 数组里面。这个“鱼钩”用 linux-2.4.19/include/linux/netfilter.h 中定义的如下 struct 予以描述:               

28、60; struct nf_hook_ops          struct list_head list;     nf_hookfn *hook;     int pf;     int hooknum;     int priority;     ;     &#

29、160;               我们看到,“鱼钩”的本质,是一个 nf_hookfn 函数。这个函数将对被钓上来的 IP packet 进行初步的处理。那么,这些“鱼钩”是由谁来放置到 nf_hooks 数组里面的呢?答案是,各个 table。熟悉 iptables 管理工具的读者朋友们应该了解,一个 table 就是一组类似的防火墙 rules 的集合。iptables 里面默认定义了三个 table:filter,mangle,和 nat。举 f

30、ilter table 为例,它是在 linux-2.4.19/net/ipv4/netfilter/iptable_filter.c 中实现的一个 kernel module。在这个 module 的初始化过程中,它会调用 nf_register_hook() 向 netfilter 的核心代码注册一组“鱼钩”。这个注册过程,实际上,也就是把“鱼钩”放到“垂钓点”的过程。“垂钓点”的具体位置,由 nf_hooks 数组的下标具体说明。    ipt_do_table()    我们具体看到 linux-2.4.1

31、9/net/ipv4/netfilter/iptable_filter.c 也就是 filter table 的实现代码,就发现 filter table 中的“鱼钩”上的 nf_hookfn 函数,主要是在调用 ipt_do_table() 函数。这是一个定义在 linux-2.4.19/net/ipv4/netfilter/ip_tables.c 中的函数。前面提到过,一个 table 就是一组防火墙 rules 的集合。显然,ipt_do_table() 函数将要做的事情,就是按照 table 中存储的一条又一条的 rules 来处理被“钓”上来的 IP packet。 

32、60;  table 里面存放了这个 table 中所有的防火墙 rules。但是并不是所有的 rules 都要拿过来,按照它审查一下这个 packet。事实上,这个 packet 是从哪个“鱼钩”上被钓上来的,就只有和那个“鱼钩”相关的 rules 才被拿过来,用来审查这个 packet。这个机制,就为每个 table 实现了多个 chain,而每个 chain 上又有多个 rules。而且,我们立刻看到,一个 chain 是和 IPv4 协议栈上的一个“垂钓点”相对应的。熟悉 iptables 用户空间管理工具的使用的读者朋友们应该立刻就会注意到这一点了。 &

33、#160;  在 linux-2.4.19/include/linux/netfilter_ipv4/ip_tables.h 中定义了 table 中的 rule 的存放格式,如下:                 /* This structure defines each of the firewall rules. Consists of 3     parts whic

34、h are 1) general IP header stuff 2) match specific     stuff 3) the target to perform if the rule matches */     struct ipt_entry          struct ipt_ip ip;     /* Mark with fields that we care about.

35、 */     unsigned int nfcache;     /* Size of ipt_entry + matches */     u_int16_t target_offset;     /* Size of ipt_entry + matches + target */     u_int16_t next_offset;     /* Ba

36、ck pointer */     unsigned int comefrom;     /* Packet and byte counters. */     struct ipt_counters counters;     /* The matches (if any), then the target. */     unsigned char elems0;  

37、60;  ;                     一个 entry 就是一个 rule。一个 entry 主要由两部分组成。一部分,是一系列的 matches;另一部分,是一个 target。这若干个 match 所要回答的问题,是相关的 packet 和本条 rule 是否匹配。而这个 target 所要回答的问题,是一旦 packet 匹配上以后,该拿这个 packet 怎么办?

38、也就是要由 target 来决定这个匹配的 packet 今后的命运了。开头的 struct ipt_ip 的定义如下:                 struct ipt_ip      /* Source and destination IP addr */     struct in_addr src, dst;   &

39、#160; /* Mask for src and dest IP addr */     struct in_addr smsk, dmsk;     char inifaceIFNAMSIZ, outifaceIFNAMSIZ;     unsigned char iniface_maskIFNAMSIZ, outiface_maskIFNAMSIZ;     /* Protocol, 0 = ANY */  &

40、#160;  u_int16_t proto;     /* Flags word */     u_int8_t flags;     /* Inverse flags */     u_int8_t invflags;     ;             

41、        我们立刻可以看出来,在 struct ipt_ip 里面记录了关于这个 rule 所要匹配(match)的 packet 的一些特征。    match 和 target    netfilter 核心部分提供了一个分析、处置 packet 的架构,但是核心部分代码并不具体的去分析、处置 packet。这个具体的分析、处置的任务被交给其它的 module 来完成。核心部分代码可以根据 table 中记录的 rules 信息,来把

42、packet 交给能够处理相应的 rules 的 module 代码。那么,核心代码如何了解哪一个 module 可以处理哪一类的 rules 的呢?这要由各个相应的 modules 起动的时候,主动去向核心代码注册,ipt_register_target() 或者是 ipt_register_match()。这个注册过程,主要就是通知核心代码,本 module 有一个 target() 函数,可以决定 packet 的命运;或者是,本 module 有一个 match() 函数,可以判定一个 packet 是否符合 rules 的匹配要求。    这就

43、提示我们,如果要写自己的防火墙模块,镶嵌在 netfilter 的架构中的话,我们主要要做的任务,就是向 netfilter 核心注册 ipt_register_target() 或者 ipt_register_match()。    iptables 管理工具    最后,要说明的是 iptables,这个位于用户空间的管理工具。前面我们看到了,netfilter 在内核空间的代码根据 table 中的 rules,完成对 packet 的分析和处置。但是这些 table 中的具体的防火墙 rules,还是必须由系统管理员亲自编写。ke

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论