当前位置: 代码迷 >> 综合 >> Netfilter 学习
  详细解决方案

Netfilter 学习

热度:5   发布时间:2024-01-09 10:32:37.0
一、Netfiter简介 ---From netfilter.samba.org/what is netfilter
     从Linux Kernel 2.4开始,一个新的网络包过滤框架替代了原来的ipchains/ipfwadm系统,那就是netfilter和iptables。作为内核网络协议堆的一个扩展子集,netfilter可以在内核空间非常高效的进行包过滤,网络地址转换(NAT)和包重组。同时,新的 Netfilter/Iptables框架设计采取了更优的软件设计策略,让全世界的网络程序员可以针对各自的应用的开发各种不同的应用模块。
二、Linux IP网络协议栈分析 ---The journey of a packet through the linux 2.4 network stack
   为了更好的了解Netfilter的工作机理,非常有必要先来分析一下Linux2.4系列内核对于网络数据是如何处理的。以下的分析全部基于以太网和IPv4协议。
2.1 收到数据,中断发生
通常的,当一块网卡接收到属于其自己MAC地址或者广播的以太网络数据帧时,就会引发一个中断,网卡驱动的中断处理程序获得机会,通过I/O,DMA复制网络帧数据到内存中。然后网络驱动程序将创建一个skb结构,将网络帧数据填充,设置时间戳,区分类型后,将skb送入对应的包接收队列(其实就是添加到系统中的一个双向链表中)。在新的2.4内核中,通过软中断(softirq)方式实现将数据包从队列中提取,传递到协议处理堆栈。和以前2.2/2.0 内核采用方式相比,软中断方式的最大的优点是支持针对多处理器的优化。在这里,网卡驱动的中断处理程序将调用 include/linux/interrupt.h:__cpu_raise_softirq()发起一个软中断,然后完成使命,退出。
2.2数据接收软中断
内核调用kernel/softirq.c:do_softirq()执行数据包接收软中断(NET_RX_SOFTIRQ),将skb从CPU的接收队列中取出来,交给对应IPv4协议处理程序。协议处理程序将对传入的数据包进行一些完整性监测,如果监测失败,则将数据包丢弃。通过完整性监测以后,将进行一些必要的清理操作,去掉可能多余的填充数据,并且重新计算数据包的长度。接下来,数据包将进入Netfilter的第一个HOOK函数 NF_IP_INPUT的控制范围。从Hook函数出来以后,程序流程将转移到net/ipv4/ipv_input.c:ip_rcv_finish (),进行数据包的目的地址的判断,送给路由选择程序,决定数据包是(1)送往本地的应用进程(ip_local_deliver);(2)转发到其他主机(ip_forward);(3)多播转发(ip_mr_input);(4)错误,丢弃(ip_error)。
2.3数据转发
我们来看那些需要转发的数据包。
对于数据包的转发工作,将由net/ipv4/ip_forward.c:ip_forward()来完成。首先检查IP包的TTL,如果小于0,则丢弃之,并且向源主机发送TTL超时错的ICMP包,否则,将TTL减1。然后比较包大小和目标网络接口的MTU,如果IP包标记不允许分包,则丢弃该数据包,并向源主机发送ICMP包,告知数据需要分包。接下来是Netfilter要处理的另一个HOOK地点:NF_IP_FORWARD Hook。如果我们在iptables规则中跳转到ACCEPT,则这里的HOOK将返回NF_ACCEPT,于是数据包将会顺利的通过 ip_forward_finish(),准备发送到另外的网络。而数据包在最终发送之前,将会落入Netfilter的第三个Hook陷阱,那就是 NF_IP_POST_ROUTING,满足规则的数据包最终被送入网卡驱动程序发送到另外的网络。
三、Netfilter框架分析
通过上面的分析,可以确定,Netfilter事实上是内核网络协议栈中的一些HOOK集合。
如图所示
user posted image
上图的数字分别代表了Netfilter安插在内核中的5个HOOK
当数据包通过了完整性检测以后,就会从上图左边流入,首先流过NF_IP_PRE_ROUTING HOOK[1],接下来由网络协议栈的决定数据包是否送给本地进程,还是需要转发给其他网卡设备,发往本地进程的数据包将流过 NF_IP_LOCAL_IN HOOK[2],而需要转发给其他网卡设备的数据包则流过NF_IP_FORWARD HOOK[3]。在数据最终发送到网卡驱动程序之前,还要流过NF_IP_POST_ROUTING HOOK[4]。而对于本地进程发送的数据包,则会首先流过NF_IP_LOCAL_OUT HOOT[5],然后从HOOK[4]流出。
由此可见,5个HOOK的位置,掌管了全部数据包的可能出入口,我们只要在对应的位置对数据包进行操作,就能实现对数据包的各种处理。
当HOOK截获数据包以后,将根据一些规则判断数据包的命运。用户通过注册一些规则检测函数来检测数据包,内核/Netfilter将根据这些函数的返回值来决定数据包的命运。返回值有以下5种:
NF_ACCEPT: 允许数据包通过
NF_DROP: 丢弃该数据包
NF_STOLEN: 告诉内核,该数据包已被处理。
NF_QUEUE: 将数据包排入队列,通常是将数据包发送给用户进程空间处理NF_REPEAT: 再一次调用本HOOK
四、用Netfilter/Iptables设计安全防火墙
在Netfilter的框架结构上,我们可以利用iptables应用程序来和内核通信,制定一系列规则,对数据包进行处理。iptables 内建了3个表,filter表,nat表和mangle表,分别用于实现包过滤,网络地址转换和包重构的功能。本文中,主要针对filter表进行操作。最常用的,对于防火墙来说,就是利用在filter表中指定一系列规则(rules)以实现对数据包进行过滤的操作。在filter表中只允许对数据包进行接受,丢弃的操作,而无法对数据包进行更改。
在iptables中规定,链(chains)是规则(rules)的集合, filter表包含3个chain,分别为INPUT,FORWARD,OUTPUT。通过前面的分析,可以确定该3条规则链将分别在:(1)数据包在送入本地进程之前、(2)数据报在内核通过路由算法即将被转发之前,和(3)本地进程向网络发送数据包前三个关键HOOK位置发挥作用。
为了防止外部入侵,更多时候,我们只要在INPUT链中进行过滤即可。现给出一个简单的例子:
首先,设定缺省的策略Policy为DROP,这样,当内核遍历INPUT CHAINS的时候,如果没有满足任何规则,则将数据包按照缺省策略操作。
#iptables -P INPUT DROP
接下来,针对已经建立连接的数据包,我们允许其畅通无阻。
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
然后逐步开放对应的服务端口,例如,需要提供HTTP服务,开放80端口,命令如下:
iptables –A INPUT –p tcp –dport 80 –j ACCEPT
也许,有时候,我们并不希望简单的丢弃我们不需要的数据包,因为,当远方主机发送SYN数据包过来的时候,我们如果只是简单的丢弃的话,对方主机还是会持续发送SYN数据包过来,直到多次超时失败才放弃。所以我们可以用REJECT target来拒绝数据包的同时,发送给对方主机一个RST包,终止对方连接,用下面的命令取代上面的命令即可。
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
五、实际应用案例
前些日子,Nimda病毒盛行,本人APACHE HTTP主机的LOG文件每天莫名增长近1M,上面保存了大量的%c0%c1/cmd.exe?/c+dir等试图利用IIS的Unicode漏洞访问记录。事实上这些记录未必是有意图的攻击者的痕迹,而是大量泛滥的Nimda扫描网段,试图感染IIS主机的杰作。而且,泛滥的信息,很可能掩盖某些真正的攻击信息,所以,有必要针对这类情况配置出对应的防火墙策略。Iptables 2.5+以上的版本提供了一个新的string模块专门实现针对字符串内容的过滤。
首先准备好2.4以上的内核代码,目前的稳定版本是2.4.18,可以从 http://kernel.org处获得。然后到 netfilter.samba.org处获得最新的iptables代码,目前版本是1.2.6b,编译iptables用户进程应用程序以后,执行 make patch-o-matic,选择给内核补上string match模块。
  运行内核配置程序,就会发现,在Network OptionsIP Netfilter Config中多出了String match选项,选择编译成模块(M)。重新编译内核,成功之后,iptable就具备字符串过滤的功能了。
我们只需对已连接的HTTP数据包进行处理。而cmd.exe之类的URL请求是在HTTP会话建立以后,通过POST/GET命令发送的。所以,只需针对连接到80端口的数据包进行处理即可。如果内容中包含”exe?/c+”等敏感内容,则立即丢弃。
接下来是指定防火墙规则,我们自定义一个规则链。如下:
# anti-worm chain
iptables -N anti-worm
iptables -A anti-worm -p tcp --dport 80 -m string --string "/default.ida" -j DROP
iptables -A anti-worm -p tcp --dport 80 -m string --string ".exe?/c+" -j DROP
iptables -A anti-worm -p tcp --dport 80 -j ACCEPT
然后,在整体的规则中,只需加入下面的命令即可:
iptables -A INPUT -p tcp --destination-port 80 -j anti-worm
我们可以在IE中测试被保护的HTTP Server,当输入正常的URL请求的时候,一切正常。当你在URL后边添加诸如”cmd.exe?/c+dir”的时候,IE将无法获得服务器返回信息,因为该数据包已经被DROP了。
六 总结
Netfilter/Iptables的包过滤架构是Linux内核开发人员通过对ipfw/ipfwadm/ipchains等早期的包过滤程序的开发经验和全世界用户反馈的分析,重新设计,改造而形成的相对成熟的Linux内核包过滤框架。同时,由于公开源代码,全世界的网络开发人员针对各自的需要和网络出现的新情况,在义务的开发着对应的模块,这极大的丰富了iptables功能。采用netfilter/iptables设计的网络防火墙,完全可以媲美专业的网络防火墙,更重要的是,他的成本几乎为零。
参考资料:
[1]《what is netfilter》 http://netfilger.samba.org
[2] Harald Welte《skb - Linux network buffers》
[3] Rusty Russell and Harald Welte 《Linux netfilter Hacking HOWTO》
[4] Rusty Russel Linux 2.4 Packet Filtering HOWTO
[5]《TCPIP协议详解卷1:协议 影印版》 机械工业出版社