前言

最近一直在寻找能拦截linux原始套接字数据包的方法,煞费苦心,终于功夫不负有心人,找到了一种方法可以实现,将这种方法分享给大家。

一、环境介绍

本次试验是基于CentOS7.6.1810,内核版本为3.10.0.957.el7.x86_64。

二、能够拦截linux网络数据的其他方法

先说一下我做这个试验时寻找的一些方法,也许其他方法也是可以实现的。

1、netfilter框架

这个框架的拦截发生在网络层,如果不考虑原始套接字的情况,是推荐使用这种方法的。这个框架网上的资源挺多的,有兴趣的可以自己去查。

2、iptables 防火墙

这个linux自带的防火墙功能的拦截也是发生在网络层,不能拦截链路层的原始套接字数据包。

3、BPF/eBPF框架

伯克利包过滤器,是一种基于伪汇编的底层数据包过滤器,他可以根据配置的规则过滤数据包,但好像不能对数据包做修改。我也不太清楚这种方法,这里就放一个链接(eBPF用于Linux防火墙数据包过滤https://blog.csdn.net/dog250/article/details/102884567),自己去研究吧。

4、ebtables强制原始套接字数据包通过iptables

这种方法需要网卡的连接方法为桥接模式。这里也只放个链接(http://ebtables.netfilter.org/br_fw_ia/br_fw_ia.html

5、LSM安全模块框架

一种内核挂钩的方法,LSM安全模块是linux内核开发时就事先在内核关键路径上设置了挂钩函数,通过这些函数去进行函数调用执行的权限管理,理论上是可以设置我们的hook函数进行拦截的,但我没有测试成功。

三、ftrace框架

这才是这篇文章的重点,ftrace框架。

1、ftrace框架介绍

看这篇文章吧,他解释的更好。简单来说就是ftrace是hook内核函数的方法,他本身的作用是用于跟踪和调试内核,但后来被用来拦截网络数据包了。
https://www.apriorit.com/dev-blog/546-hooking-linux-functions-2

2、源代码下载

这是githup上找到的,分享给大家,对照源代码去看上一个链接的文章说明,更容易明白。
https://github.com/ilammy/ftrace-hook.git

3、hook网络发送的函数

要想拦截所有网络数据包,就得在“总路口”进行拦截。下图是linux网络发送的部分过程图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再查看内核发现,dev_queue_xmit函数是一个中间函数,所有最佳拦截就是dev_queue_xmit函数。在源代码的基础上加入我们的函数,这样就可以在自己的hook函数中做相应的逻辑处理 了。代码添加如下:

static asmlinkage int (*real_dev_queue_xmit)(struct sk_buff *skb);
static asmlinkage int fh_dev_queue_xmit(struct sk_buff *skb)
{
	long ret;
	pr_info("before fh dev queue xmit\n");
	//这里做逻辑判断,自己的处理函数调用挂载
	ret = real_dev_queue_xmit(skb);
	pr_info("after fh dev queue xmit\n");
	return ret;
}
static struct ftrace_hook demo_hooks[] = {
	//第一条是我们加进去的要hook的函数
	HOOK("dev_queue_xmit", fh_dev_queue_xmit, &real_dev_queue_xmit),
	HOOK("sys_clone",  fh_sys_clone,  &real_sys_clone),
	HOOK("sys_execve", fh_sys_execve, &real_sys_execve),
};
4、编译遇到的问题

如果编译不过,尝试修改图中的宏定义为1。
在这里插入图片描述

5、内核调试

内核调试时是不能直接打印调试信息的,需要用dmesg命令参看内核日志,就可以看到dev_queue_xmit函数被拦截。

Logo

更多推荐