利用Linux Netfilter框架实现Linux内核模块阻断HTTP数据包

利用Linux Netfilter框架实现Linux内核模块阻断HTTP数据包_第1张图片

主要参考内容:

  1. netfilter数据包过滤【https://tcspecial.iteye.com/blog/2174784】(很旧版netfilter下阻断http包)
  2. Linux内核编程 -- 从HelloWord到基于NetFilter的Linux驱动Demo【https://blog.csdn.net/xushuzhan/article/details/78843218】(很详细,从如何实现helloworld内核模块到netfilter,版本略微旧)
  3. The Linux Kernel Module Programming Guide【http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html】(英文,如何实现内核模块)
  4. Linux Kernel Communication — Part 1 Netfilter Hooks【https://medium.com/@GoldenOak/linux-kernel-communication-part-1-netfilter-hooks-15c07a5a5c4e】(英文,现行版netfilter下阻断所有非dns的udp包,结构体赋值方式与1/2略不同)
  5. 利用netfilter抓包(一)----------netfilter介绍【https://blog.csdn.net/Sophisticated_/article/details/83542395】(现行版netfilter中关键函数和结构体的参数介绍)
  6. Netfilter源码【https://elixir.bootlin.com/linux/v5.1/source/include/linux/netfilter.h】

以及

License介绍【https://blog.csdn.net/lihaoweiv/article/details/6602261】【https://blog.csdn.net/liaomin416100569/article/details/54133645】

代码主要参考1(疯狂报错

主要报错来源:

  1. 版本更替,hookfn函数、nf_hook_ops结构体、register函数等有变。找源码!看源码!
  2. 应该阻断的是source port = 80,而不是dest port = 80

利用Linux Netfilter框架实现Linux内核模块阻断HTTP数据包_第2张图片

利用Linux Netfilter框架实现Linux内核模块阻断HTTP数据包_第3张图片

代码如下,dmesg可看端口日志

#include   
#include   
#include   
// #include 
// #include 
#include   
// #include 
// #include  
#include   
#include 
#include  
  
static unsigned int NET_HookLocalIn(
	void *priv, 
	struct sk_buff *skb, 
	const struct nf_hook_state *state)
{
	int retval = NF_ACCEPT;
	if(skb){	
		struct tcphdr *tcph;
		struct iphdr *iph;
		struct udphdr *udph;

		iph = ip_hdr(skb);  // 获取ip头  
		
		if( iph->protocol == IPPROTO_TCP )  
		{
			tcph = tcp_hdr(skb);
			printk("tcp, %u -- %u\n", htons(tcph->source),htons(tcph->dest));
			if( htons(tcph->source) == 80 || htons(tcph->source) == 443) // 当目标端口为80/tcp or 443/tcp,则丢弃  
			{  
				retval = NF_DROP;
			}  
		}
		else if( iph->protocol == IPPROTO_UDP )  
		{
			udph = udp_hdr(skb);
			printk("udp, %u -- %u\n", htons(udph->source),htons(udph->dest));
			if( htons(udph->source) == 443)	// 当目标端口为443/udp,则丢弃  
			{
				retval = NF_DROP;
			}  
		}
	}
	return retval;  
}

static struct nf_hook_ops net_hooks_ops = 
{
	.hook		= NET_HookLocalIn,	// 发往本地数据包  
	.pf			= PF_INET,  	//protocol family, ipv4即这个
	.hooknum	= NF_INET_LOCAL_IN,      //hook所在的位置
	.priority	= NF_IP_PRI_FIRST,      //优先级
};

static int __init net_hooks_init(void) 
{
	nf_register_net_hook(&init_net, &net_hooks_ops);
	return 0; 
}

static void __exit net_hooks_exit(void)
{
	nf_unregister_net_hook(&init_net, &net_hooks_ops);
} 

module_init(net_hooks_init); 
module_exit(net_hooks_exit); 

MODULE_LICENSE("Dual BSD/GPL");  
MODULE_AUTHOR("skyhood");  
MODULE_DESCRIPTION("Netfilter Demo");  
MODULE_VERSION("1.0");  

未解:

  1. 头文件是抄的
  2. htons()和ntohs()傻傻分不清

你可能感兴趣的:(作业,没错就是作业)