首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 开发>文章内容
Linux 防火墙在内核中的实现
来源: 作者:赵蔚 发布时间:2007-05-22  

作者:Linux/Free Software 独立技术顾问

本文介绍 Linux 的防火墙技术 netfilter/iptables 在 Linux 内核中的具体实现。

netfilter 和 Linux 防火墙介绍

Linux 的防火墙技术经历了若干代的沿革,一步步的发展而来。最开始的 ipfwadm 是 Alan Cox 在 Linux kernel 发展的初期,从 FreeBSD 的内核代码中移植过来的。后来经历了 ipchains,再经由 Paul Russell 在 Linux kernel 2.3 系列的开发过程中发展了 netfilter 这个架构。而用户空间的防火墙管理工具,也相应的发展为 iptables。netfilter/iptables 这个组合目前相当的令人满意。在经历了 Linux kernel 2.4 和 2.5 的发展以后,的确可以说,netfilter/iptables 经受住了大量用户广泛使用的考验。

本文并不打算介绍 Linux 防火墙在用户空间的管理程序 iptables 的使用。至于如何利用 netfilter/iptables 机制搭建一个可靠的 Internet 防火墙,这也不是本文感兴趣的话题。关于 iptables 的使用,读者朋友们可以参考 man iptables 的手册,也可以参考 netfilter 的核心开发者 Paul Russell 写的 Packet Filtering HOW-TO 和 NAT HOW-TO。相关的链接,请参见文后所列的参考资料目录。读者朋友们在阅读本文之前,最好能够对 iptables 的使用有一定的了解。

本文介绍 netfilter 在 Linux kernel 中的实现。如果条件允许的话,我们可能在后续的文章中将要进一步说明如何编写自己的 kernel modules 并将其镶嵌在 netfilter 的架构中,以实现自己的定制防火墙功能。值得指出的是,在 netfilter 的网站上,可以看到 netfilter 的一个子项目 patch-o-matic,其中收录了大量的各种定制 kernel modules,这些 modules 给读者朋友们开发自己的 kernel modules,提供了非常多的、很好的例子。

IPv4 代码中 netfilter 的接口

netfilter 在 Linux kernel 中的 IPv4、IPv6 和 DECnet 等网络协议栈中都有相应的实现。本文限于篇幅,将只介绍其中最让大多数读者朋友们感兴趣的 IPv4 协议栈上的 netfilter 的实现。

我们在编译 Linux kernel 的过程中一定会注意到,netfilter 是一个在编译过程中可选的部件。也就是说,用户在编译内核的过程中,可以按照自己的需要,决定是否要在自己的内核中编译进去 netfilter 的 kernel 支持。这就带给我们一个提示,实现 netfilter 的代码对于实现 IPv4 协议栈的代码的影响应该会是尽量的小,不那么引人注目才对。否则的话,IPv4 协议栈的代码维护工作就不得不和实现 netfilter 的代码的维护工作搅在一起,让人头疼了。

事实也的确如此,IPv4 协议栈为了实现对 netfilter 架构的支持,在 IP packet 在 IPv4 协议栈上的游历路线之中,仔细选择了五个参考点。在这五个参考点上,各引入了一行对 NF_HOOK() 宏函数的一个相应的调用。这五个参考点被分别命名为 PREROUTING,LOCAL-IN,FORWARD,LOCAL-OUT 和 POSTROUTING。关于这五个参考点的含义,在 iptables 的使用说明中有准确的叙述,相信读者朋友们都应该了解了。从如下的 grep 输出,我们可以看到 IPv4 协议栈实现代码对 NF_HOOK() 宏函数的调用:


zhaoway@qhq ~/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:/* Don't just hand NF_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:/* 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_output.c:111:/* Don't 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,
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,
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 */
ipmr.c:1211:NF_HOOK(PF_INET, NF_IP_FORWARD, skb2, skb->dev, dev,
zhaoway@qhq ~/linux-2.4.19/net/ipv4 $

NF_HOOK() 这个宏函数,定义在 linux-2.4.19/include/linux/netfilter.h 里面。当 #ifdef CONFIG_NETFILTER 被定义的时候,就转去调用 nf_hook_slow() 函数;如果 CONFIG_NETFILTER 没有被定义,则从 netfilter 模块转回到 IPv4 协议栈,继续往下处理。这样就给了用户在编译 kernel 的时候一个选项,可以通过定义 CONFIG_NETFILTER 与否来决定是否把 netfilter 支持代码编译进内核。从这个函数的名称,我们也可以猜到,可以把 IPv4 协议栈上的这五个参考点,形象的看成是五个钩子。IP packet 在 IPv4 协议栈上游历的时候,途经这五个钩子,就会被 netfilter 模块钓上来,审查一番,并据审查的结果,决定 packet 的下一步命运:是被原封不动的放回 IPv4 协议栈,继续游历;还是经过一些修改,再放回去;还是干脆丢弃掉算了?

netfilter 的核心模块

“鱼钩”和“垂钓点”

IP packet 被 NF_HOOK() 从 IPv4 协议栈上钓出来以后,就进入 linux-2.4.19/net/core/netfilter.c 中的 nf_hook_slow() 函数进行处理。这个函数干的主要事情,就是根据 nf_hooks[] 数组,开始处理 packet。准确地说来,上一段讲到的 IPv4 协议栈上的五个参考点,并不是“钓鱼的钩子”,而是“允许垂钓的地点”。换句话说,IPv4 协议栈上定义了五个“允许垂钓点”。在每一个“垂钓点”,都可以让 netfilter 放置一个“鱼钩”,把经过的 packet 钓上来。那么 netfiler 的“鱼钩”都放在什么地方?就放在 nf_hooks[][] 数组里面。这个“鱼钩”用 linux-2.4.19/include/linux/netfilter.h 中定义的如下 struct 予以描述:

共3页: 上一页 1 [2] [3] 下一页
 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·嵌入式Linux系统下图形库讲解及
·Qt/Embedded在嵌入式Linux中的应
·Linux系统环境下的Socket编程详
·在 Fedora Core 5 上体验 Aiglx
·使用 Linux 系统调用的内核命令
·Linux 2.6.11内核文件IO系统调用
·在Linux中创建静态库和动态库
·嵌入式Linux:uClinux操作系统移
·Linux操作系统下的多进程编程(
·嵌入式系统 Boot Loader 技术内
·Linux操作系统的源代码目录树结
·Linux用户态与内核态的交互讲解
  相关文章
·剖析RedHat Linux中三个重要内核
·内核空间SMP编程
·细看嵌入式Linux时代发展
·Linux系统单一内核模块编译过程
·介绍B-SHELL的一些运用方法
·Linux程式设计.Shell Script(bas
·Linux程式设计.Shell Script(bas
·Linux程式设计.Shell Script(bas
·嵌入式Linux系统的GDB远程调试的
·关于嵌入式Linux系统进程调度的
·教你一种实现嵌入式Linux系统新
·剖析Linux 2.6内核在嵌入式上的

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!