iptables可以很方便的构建系统防火墙,那它是如何实现的呢?Linux内核添加了netfilter机制,在IP协议栈上传递过程中,选择了5个检查点。利用5个检测点,查阅用户注册的回调处理函数,根据用户自定义回调函数监视进出的网络数据包。
有了上面的知识,可以实现自己的iptables。
一.编码
该示例简单拦截所有到达本机的http请求。
#ifndef __KERNEL__ #define __KERNEL__ #endif /* __KERNEL__ */ #include <linux/module.h> #include <linux/init.h> #include <linux/types.h> #include <linux/string.h> #include <asm/uaccess.h> #include <linux/netdevice.h> #include <linux/netfilter_ipv4.h> // ip4 netfilter,ipv6则需引入相应 linux/netfilter_ipv6.h #include <linux/ip.h> #include <linux/tcp.h> #define PORT 80 // 过滤http数据包 static int filter_http(char *type,struct sk_buff *pskb) { int retval = NF_ACCEPT; struct sk_buff *skb = pskb; struct iphdr *iph = ip_hdr(skb); // 获取ip头 struct tcphdr *tcp = NULL; char *p = NULL; // 解析TCP数据包 if( iph->protocol == IPPROTO_TCP ) { tcp = tcp_hdr(skb); p = (char*)(skb->data+iph->tot_len); // 注:sk_buff的data字段数据从ip头开始,不包括以太网数据帧 printk("%s: " "%d.%d.%d.%d => %d.%d.%d.%d " "%u -- %u\n" type, (iph->saddr&0x000000FF)>>0, (iph->saddr&0x0000FF00)>>8, (iph->saddr&0x00FF0000)>>16, (iph->saddr&0xFF000000)>>24, (iph->daddr&0x000000FF)>>0, (iph->daddr&0x0000FF00)>>8, (iph->daddr&0x00FF0000)>>16, (iph->daddr&0xFF000000)>>24, htons(tcp->source), htons(tcp->dest) ); if( htons(tcp->dest) == PORT ) // 当目标端口为80,则丢弃 { retval = NF_DROP; } } return retval; } static unsigned int NET_HookLocalIn(unsigned int hook, struct sk_buff *pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff*)) { return filter_http("in",pskb); } static unsigned int NET_HookLocalOut(unsigned int hook, struct sk_buff *pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff*)) { return filter_http("out",pskb); } static unsigned int NET_HookPreRouting(unsigned int hook, struct sk_buff *pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff*)) { return NF_ACCEPT; } static unsigned int NET_HookPostRouting(unsigned int hook, struct sk_buff *pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff*)) { return NF_ACCEPT; } static unsigned int NET_HookForward(unsigned int hook, struct sk_buff *pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff*)) { return NF_ACCEPT; } // 钩子数组 static struct nf_hook_ops net_hooks[] = { { .hook = NET_HookLocalIn, // 发往本地数据包 .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_INET_LOCAL_IN, .priority = NF_IP_PRI_FILTER-1, }, { .hook = NET_HookLocalOut, // 本地发出数据包 .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_FILTER-1, }, { .hook = NET_HookForward, // 转发的数据包 .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_INET_FORWARD, .priority = NF_IP_PRI_FILTER-1, }, { .hook = NET_HookPreRouting, // 进入本机路由前 .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_INET_PRE_ROUTING, .priority = NF_IP_PRI_FILTER-1, }, { .hook = NET_HookPostRouting, // 本机发出包经路由后 .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_INET_POST_ROUTING, .priority = NF_IP_PRI_FILTER-1, }, }; static int __init nf_init(void) { int ret = 0; ret = nf_register_hooks(net_hooks,ARRAY_SIZE(net_hooks)); // 安装钩子 if(ret) { printk(KERN_ERR "register hook failed\n"); return -1; } return 0; } static void __exit nf_exit(void) { nf_unregister_hooks(net_hooks,ARRAY_SIZE(net_hooks)); // 卸载钩子 } module_init(nf_init); module_exit(nf_exit); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("kettas"); MODULE_DESCRIPTION("Netfilter Demo"); MODULE_VERSION("1.0.1"); MODULE_ALIAS("Netfilter 01");
二.测试
上图发现当没启动netfilter_test.ko时,192.168.4.190可以正常接收192.168.5.212发送过来的hello,当启动驱动后,192.168.4.190无法收到来自192.168.5.212发送的world字符串。
三. 应用拦截
在用户上网行为管控场景下,需要对识别的应用放行或拦截,有以下两种方案实现。
1. 内核态
通过netfilter直接DROP数据包。内核态性能最优,但开发调试难度较大。
2. 用户态
旁路方式采集数据包,然后直接伪造HTTP,TCP,UDP等协议的应答,后到的数据包会被协议丢弃,从而达到阻断应用的目的。
用户态开发调试效率高,但对采集性能提出很高的要求。但是在某些嵌入式环境下,由于资源限制,无法高效采集数据包。
相关推荐
Linux网络防火墙Netfilter的数据包传输过滤原理.pdf
比较基础,但也比较全面 定义iptables/netfilter的匹配模块
Netfilter是Linux内核中的一个重要子系统,它提供了强大的网络处理能力,包括数据包过滤、网络地址转换(NAT)以及连接跟踪等功能。Netfilter的核心机制是通过一系列的hook点来拦截并处理网络数据包。这些hook点分布...
Netfilter是Linux 2.4内核实现数据包过滤、数据包处理、NAT等的功能框架。它提供了一个抽象、通用化的框架,相比之前的任何一版本Linux内核防火墙子系统都要完善强大。 Netfilter的功能框架主要包括数据包过滤、...
1. **创建过滤器类**:定义自己的过滤器,继承自ja-netfilter提供的基础过滤器类,并实现检查和处理数据包的方法。 2. **配置过滤规则链**:根据业务需求,设置过滤规则的执行顺序,将过滤器实例添加到链中。 3. **...
ja-netfilter-all是一个针对Java应用程序的网络过滤框架,它提供了对网络数据包的全面控制和解码能力。在深入探讨ja-netfilter-all之前,我们首先需要理解什么是网络过滤和解码器。 网络过滤通常指的是在网络通信中...
Linux协议栈,Netfilter框架分析文档,Linux内核中进行数据包过滤、连接跟踪、地址转换等的主要实现框架。
Netfilter是Linux内核的一部分,负责网络包的处理,包括数据包过滤、NAT(网络地址转换)、以及修改和记录网络数据包信息。iptables则是一个用户空间的应用程序,用于定义规则表和链,通过这些规则来控制Netfilter...
Ja-Netfilter-All插件的核心功能在于帮助开发者更便捷地处理网络过滤规则,尤其是在构建网络应用时,能够高效地实现数据包的捕获、分析和过滤。这个插件集成了对Netfilter框架的支持,Netfilter是Linux内核中的一个...
Netfilter和Iptables是Linux内核中用于数据包过滤、网络地址转换(NAT)和数据包修改的核心组件。Netfilter是一种框架,提供了一系列的钩子(hooks),允许在数据包经过内核的特定点时插入自定义处理函数。而...
2. **数据包过滤**:在网络通信中,数据包过滤是指对网络流量进行检查,根据预设规则决定是否允许其通过。Ja-Netfilter可能提供了这样的功能,允许用户设定规则以控制网络流量。 3. **Java代理(Proxy)**:Ja-...
ja-netfilter插件主要关注网络数据包过滤,它允许用户对IDEA中发送和接收的HTTP请求进行拦截、修改和分析,极大地提升了开发者在调试网络相关的应用程序时的便利性。在实际开发过程中,尤其是处理Web服务或者涉及到...
ja-netfilter是一个专门为Java应用程序设计的网络过滤框架,它的核心目标是帮助开发者对进出Java应用的网络流量进行拦截、分析和控制。这个框架允许程序员在不修改原代码的情况下,通过插件化的机制来实现网络数据包...
- 数据包过滤是netfilter的一个关键功能,允许根据预设的规则对数据包进行拦截或放行。 - 这些规则可以通过命令行工具(如iptables)进行配置。 3. **NAT与伪装** - Network Address Translation (NAT) 是...
这个文件可能包含源代码,这通常意味着它提供了实现或解析网络数据包过滤技术的具体程序。让我们深入探讨这两个核心概念。 **包过滤(Packet Filtering)** 包过滤是一种网络安全策略,它涉及在网络层检查进出网络...
Linux内核中的netfilter架构有以太网层...Netfilter为内核中实现防火墙功能、数据包过滤、修改、连接跟踪、应用层网关alg等的载体。而linux应用层则提供了iptables这样功能强大的实现netfilter功能的配置管理工具。
Netfilter是Linux 2.4内核的一个子系统,Netfiler使得诸如数据包过滤、网络地址转换(NAT)以及网络连接跟踪等技巧成为可能,这些功能仅通过使用内核网络代码提供的各式各样的hook既可以完成。这些hook位于内核代码中...
Netfilter框架是Linux内核中的一个核心组件,自2.4.x版本开始引入,它提供了一个通用且抽象的架构,允许开发者实现数据包过滤、网络地址转换(NAT)和连接跟踪等功能。Netfilter框架主要涉及到五个关键点,即"A"、"B...
Netfilter是一个功能强大的内核框架,它为Linux系统提供了数据包过滤、网络地址转换(NAT)、连接跟踪等核心网络功能。通过该框架,开发人员可以编写内核模块来扩展其功能。Netfilter与Xtables/iptables紧密关联,后...
netfilter是Linux内核的网络包过滤和转换框架,netfilter_queue是其一部分,允许用户空间程序参与网络数据包处理,而NAT是一种网络技术,用于在共享网络中隐藏内部网络拓扑,并管理对外连接。 总结来说,利用...