TDI网络过滤驱动应用(一)

news2024/11/27 9:52:25

文章目录

  • TDI网络过滤驱动应用
    • 1. 技术概览
    • 2. 数据包的抓取
    • 3. 应用实例
      • 3.1 TrafficShaper(限流)
      • 3.2 DnsRedirector(DNS重定向)
      • 3.3 TcpRedirector(TCP重定向)
    • 4. 总结与参考

TDI网络过滤驱动应用

在前面的文章中,我们分析了TDI网络过滤驱动的基本开发框架以及TDI网络过滤驱动框架下面防火墙实例tdifw的实现,可以参考:

  1. TDI网络过滤驱动开发指南。
  2. TDI网络过滤驱动之tdifw实现原理分析。

对于TDI网络过滤驱动下面的防火墙应用,是TDI驱动最简单的一种应用场景,我们只需要对TDI_CONNECTtdi_event_connecttdi_send_datagramtdi_event_receive_datagram消息/回调进行防火墙规则处理即可。

下面我们分析一下TDI网络过滤驱动的其他应用,包括:

  1. 进程流量限定。
  2. DNS重定向代理。
  3. TCP重定向代理。

这些例子相比TDIFW防火墙将会复杂很多,例如最简单的流量限定。我们需要对发送和接收数据进行限流操作的话,需要对发送的IRP以及接收的数据进行缓存和挂起操作,当低于流量限定的时候再激活操作。整个过程涉及到数据接收的TDI请求重注入,相比防火墙的拦截来说要复杂很多。

1. 技术概览

我们先来看一下整个TDI网络驱动应用的框架,如下:
在这里插入图片描述

在上述框架中:

  1. 应用程序发起的网络请求或者底层来的网络数据包都先放入IoQueue队列中,然后将整个数据置于PENDING状态。
  2. 将数据包通过RequestQueue队列来进行其他处置,例如可以如下:
    1. 将数据包通过IRP请求传递给用户层,让用户层计算流量或者进行UDP转发(TCP连接转发)等。
    2. 可以在RequestQueue延迟完成数据包的传递,达到流量限定的目的。
    3. 在用户的进行数据包的DUMP(类似TCPDUMP工具进行网络抓包)。

2. 数据包的抓取

通过上面我们得知,TDI驱动有一个重要的操作,就是需要对网络数据包进行抓取,将数据包抓取到用户层,提供给用户层做各种分析。对于TCP数据我们有如下消息可以采集:

  1. IRP_MJ_CREATE:创建地址对象和连接对象。
  2. TDI_SEND:采集TCP/UDP数据被发送的事件,我们可以从IRP中提取发送的数据,用来采集本机发出去的数据。
  3. TDI_RECEIVE:采集本机主动接收数据的事件。
  4. TDI_CONNECT:TCP的连接请求,我们可以替换连接请求的数据,达到TCP代理的功能。
  5. TDI_EVENT_CONNECT:被动接收连接的事件,改事件只能用作通知功能。
  6. TDI_EVENT_RECEIVE/TDI_EVENT_RECEIVE_EXPEDITED:接收数据包的事件,抓取该事件我们可以采集本机接收的数据包信息。

对于UDP数据我们有如下事件可以采集:

  1. IRP_MJ_CREATE:创建地址对象。
  2. TDI_SEND/TDI_SEND_DATAGRAM:采集UDP数据被发送的事件,我们可以从IRP中提取发送的数据,用来采集本机发出去的数据。
  3. TDI_RECEIVE_DATAGRAM:采集本机主动接收数据的事件。
  4. TDI_EVENT_RECEIVE_DATAGRAM:接收UDP数据包的事件,抓取该事件我们可以采集本机接收的数据包信息。

对于上述所有的事件,可以从用户层的处理来分为两类:

  1. 通知类。通知类事件是通知用户层有什么事件发生,例如当UDP接收到IRP_MJ_CREATE消息的时候,可以得到UDP_CREATED被创建的消息。
  2. 决策类。决策类是需要用户层对该消息进行响应的事件,例如TCP_CONNECTED响应,需要我们对建立的连接请求进行决策(例如TCP的连接代理)。

通知类主要是通知用户层当前TDI的各种状态和情况;而决策类的事件是整个事件采集的核心,我们可以对数据进行加密或者解密,对请求进行代理转发,或者对数据进行审计。

3. 应用实例

下面我们来看一下如下TDI实例的应用,包括:

  1. 进程流量限定。
  2. DNS重定向代理。
  3. TCP重定向代理。

3.1 TrafficShaper(限流)

流量限定主要实现的原理是对send, recv, sendto, recvfrom等数据长度进行统计,在单位时间内数据量的大小如果超过限流大小就暂停数据的发送和接收,实现大致如下:

virtual void tcpReceive(ENDPOINT_ID id, const char * buf, int len)
{
    bytesIn += len;
    if (bytesIn > ioLimit)
    {
        suspendLimit(...);
    }
}

virtual void tcpSend(ENDPOINT_ID id, const char * buf, int len)
{
    bytesOut += len;
    if (bytesOut > ioLimit)
    {
        suspendLimit(...);
    }
}

virtual void udpReceive(ENDPOINT_ID id, const char * buf, int len)
{
    bytesIn += len;
    if (bytesIn > ioLimit)
    {
        suspendLimit(...);
    }
}

virtual void udpSend(ENDPOINT_ID id, const char * buf, int len)
{
    bytesOut += len;
    if (bytesOut > ioLimit)
    {
        suspendLimit(...);
    }
}

除了在数据接收或者发送的回调函数中统计流量信息之后,我们需要额外创建一个线程,该线程统计单位事件内流量的状态:

  1. 如果单位事件内流量超出限流,那么暂停数据的收发。
  2. 如果单位事件内流量低于限流,那么恢复数据的收发。

那么suspendLimit怎么暂停数据的收发呢?方法就是针对TDI_SEND这种发送请求,将其IRP挂起,不再进行发送处理;等到流量恢复的时候再次进行发送。

3.2 DnsRedirector(DNS重定向)

我们知道,如果使用gethostbyname函数我们可以获取主机名对应的IP地址信息,该函数如下:

hostent * gethostbyname(
  const char *name
);

例如我们浏览器访问网站的时候,就会对网站地址进行域名解析(也就是通过gethostbyname获取域名对应的IP地址)。

其实域名解析是利用DNS协议,向域名服务器发送DNS请求来查询主机名对应的主机地址的;该协议格式是固定的,并且有固定的端口,这个端口就是53,并且使用UDP协议进行发送。

因此如果我们可以对53端口的UDP数据包进行拦截加转发,那么我们就可以使用DNS查询的重定向了。

因此我们只需要响应回调函数udpSend,对53端口的数据进行转发处理,如下:

virtual void udpSend(ENDPOINT_ID id, const unsigned char * remoteAddress, const char * buf, int len)
{
    //...
}

我们对udpSend回调中的数据,可以使用socketsendto以及recvfrom发送DNS请求,并获取DNS请求的返回数据。

在这里有一个主要的操作就是recvfrom数据注入;我们在代理线程中将原始DNS数据包代理之后,然后通过recvfrom接收DNS请求的返回数据后,需要将数据重新注入给TDI驱动,让TDI驱动返回给原始进程,从而达到DNS代理的过程。

recvfrom数据注入就是将数据发送给TDI驱动之后,TDI驱动通过TDI_RECEIVE_DATAGRAM或者TDI_EVENT_RECEIVE_DATAGRAM返回数据。

3.3 TcpRedirector(TCP重定向)

其实DnsRedirector就是UDP重定向的一个例子;而TcpRedirector是TCP重定向的一个例子。TCP重定向其实应用非常广泛,例如很多VPN代理的TCP服务(TCP流量)就是通过TCP重定向来实现的。

不过本人看过一些大厂的VPN实现TCP代理用的还是LSP(Layered service provider)来做的,本文来讨论如何通过TDI驱动来实现TCP代理。

TCP代理主要是对connect进行处理,将连接的地址换成代理进程监控的地址,如下:

virtual void tcpConnectRequest(ENDPOINT_ID id, PTCP_CONN_INFO pConnInfo)
{
    //...
    memcpy(pConnInfo->remoteAddress, redirectToAddress, sizeof(pConnInfo->remoteAddress));
    //...
}

从这里我们可以看到,TCP的代理实现起来其实比较简单的,该功能最复杂的一个点是代理服务器的实现,一般要实现比较高效我们应当使用完成端口来对套接字进行监控。这里我们并不对TCP代理服务器做详细介绍。

4. 总结与参考

这里我们从三个实例(限流,UDP重定向,TCP重定向)大致了解TDI网络过滤驱动的基本应用场景;对于驱动防火墙的TDI网络过滤驱动复杂应用,我们需要将网络数据包进行截获以及重注入处理。

对于TDI网络过滤驱动更加全面的使用,我们可以参考NetFilter SDK 2,该SDK链接为https://netfiltersdk.com/,可惜的是该SDK是一个收费的SDK,不过它提供了相关的Sample代码,包括TrafficShaper,TcpRedirector,DnsRedirector和SocksProxyServer还是非常具有参考性的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1267088.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI视频智能分析识别技术的发展与EasyCVR智慧安防视频监控方案

随着科技的不断进步,基于AI神经网络的视频智能分析技术已经成为了当今社会的一个重要组成部分。这项技术通过利用计算机视觉和深度学习等技术,实现对视频数据的智能分析和处理,从而为各个领域提供了广泛的应用。今天我们就来介绍下视频智能分…

开发知识点-Maven包管理工具

Maven包管理工具 SpringBootSpringSecuritydubbo图书电商后台实战-环境设置(JDK8, STS, Maven, Spring IO, Springboot)点餐小程序Java版本的选择和maven仓库的配置视频管理系统&&使用maven-tomcat7插件运行web工程SpringTool suite——maven项目…

C#-串口通信入门及进阶扩展

目录 一、串口相关参数介绍 1、端口(COM口) 2、波特率(Baud rate) 3、起始位 4、停止位(StopBits) 5、数据位 6、校验位 7、缓存区 二、串口通信助手 三、虚拟串口工具 四、进阶扩展 1、位运算…

Sui根据资源使用情况,使gas费计量更公平

Sui的大规模并行处理需要新的方式思考gas费,即网络上处理交易的成本。在我们的工作中,我们研究计算成本和指令处理,以设计一种最佳的gas费机制。准确评估gas费不仅可以提供公平的网络分摊成本和健康的运营业务模型,还鼓励开发人员…

算法通关第十七关黄金挑战——透析跳跃问题

大家好,我是怒码少年小码。 本篇是贪心思想的跳跃问题专题,跳跃问题出现的频率很高。 跳跃游戏 LeetCode 55:给你一个非负整数数组 nums ,你最初位于数组的 第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。 …

java第20章节

一.线程简介 二.创建线程 1.继承Thread类 Thread类中常用的两个构造方法如下: public Thread():创建一个新的线程对象。 public Thread(String threadName):创建一个名称为threadName的线程对象。 继承Thread类创建一个新的线程的语法如下: public c…

网关路由器双栈配置中的IPv6相关选项解析

1、引言 讲知识往往是枯燥无味的,我们先从问题入手。家庭网关(光猫)、路由器是我们每个人或多或少都有所接触的2种设备。现在一般都是光纤入户,通常每个家庭配备一个光猫和一台家用路由器。 目前有许多网络服务已经提供了IPv6支…

视频监控管理平台/智能监测/检测系统EasyCVR设备列表显示不全是什么原因?该如何解决?

GB28181视频监控国标平台/视频云存储/安防监控EasyCVR视频汇聚平台,基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。智慧安防视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视…

java中反射知识点概念

这里写自定义目录标题 1.什么是反射--动态注入?2.反射的诞生背景3.反射的意义4.反射后可以做些什么5.反射相关的主要API6.反射的优缺点7.反射和不反射基础使用8.工厂模式使用反射8.1首先我们来看看不使用反射的情况:8.2使用反射的情况: 9.Jav…

【springboot】idea项目启动端口被占用

问题 idea本地启动springboot项目端口老是被占用 解决 关闭被占用的端口进程 步骤: 1. winR打开程序框 2. 查出被占用端口的进程id netstat -ano | finderstr 端口号 例如 netstat -ano | finderstr 81013.杀死进程 taskkill /pid 进程id -t -f 例如 taskkill /pid 2…

1688 API接口的介绍丨商品详情页接口丨搜索商品列表接口

1688,作为中国领先的B2B电子商务平台,为全球的买家和卖家提供了一站式的采购和销售服务。而它的API接口,更是开放了1688平台的核心功能,让开发者能够根据自己的需求来定制和扩展商业应用。 1688 API接口的介绍 1688 API接口提供…

使用影刀指令+python实现简单的长文本乱序加密

本文意在利用影刀指令python代码,实现一种较为简单的长文本加密和解密,流程结构分为两步: 加密原理–是把字符转为列表,利用列表random模块中的shuffle函数做随机乱序。解密原理–是利用了列表的索引追踪,先前创建字典…

Vue3-目录调整

默认生成的目录结构不满足我们的开发需求,所以这里需要做一些自定义改动。 主要是以下工作: 1.删除一些初始化的默认文件 2.修改剩余代码内容 3.新增调整我们需要的目录结构 在src文件夹下创建两个新文件夹,一个叫api(请求模…

re:Invent 2023:PingCAP 荣获亚马逊云科技 2023 年度合作伙伴奖项

2023 年 11 月 27 日 – 12 月 1 日, 2023 亚马逊云科技 re:Invent 在拉斯维加斯举办,亚马逊云科技合作伙伴奖项在合作伙伴颁奖晚会上颁布, PingCAP 荣获亚马逊云科技大中华区 “2023 年度 ISV 合作伙伴” 和 “2023 年度亚马逊云科技 Market…

dockerfile文件:copy和add 异同

相同点: 复制文件或目录: 无论是 COPY 还是 ADD 都可以将文件或目录从构建上下文复制到容器中。支持源路径和目标路径: 两者都需要指定源路径和目标路径,用于指定要复制的文件或目录在主机上的位置以及在容器中的目标路径。 不同…

Re0: 从零实现一个置顶任意窗口的小工具

前言 话不多说,先上效果: 这里展示的是通过下拉框选择窗口,让窗口显示并置顶,其实还可以直接通过快捷键(先鼠标点击要置顶的窗口,再使用CTRLSHIFTT),本文涉及到的完整代码已上传到G…

【开源】基于Vue+SpringBoot的智能教学资源库系统

项目编号: S 050 ,文末获取源码。 \color{red}{项目编号:S050,文末获取源码。} 项目编号:S050,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课…

现代风客餐阳台开放式一体布局,设计亮点。福州中宅装饰,福州装修

在现代家居设计中,开放式布局越来越受到欢迎。它不仅可以提升家居的空间感,还可以促进家人之间的交流和互动。这个客厅、餐厅、阳台一体化的设计,更是充分利用了空间,具有多重亮点。 01.玄关到客厅嵌入式一体式收纳柜 玄关是进入…

全国高校走进深算院:共话国产数据库产教融合生态建设

近日,由教育部高等学校计算机类专业教学指导委员会、全国高等学校计算机教育研究会主办,清华大学出版社、深圳市信息技术应用创新联盟承办的“2023全国高校走进信创企业研学活动”顺利举办。来自全国各地30余家高校的近80位院校领导、教师代表走进了深圳…

windows启动后直接进入指定程序并且不显示欢迎界面和windows桌面

windows启动后直接进入指定程序并且不显示欢迎界面和windows桌面 前言开机进入指定程序方法问题 浅尝GINA和Credential Providers关闭欢迎屏幕 前言 由于系统需求需要做到电脑开机后显示完windows加载页面就直接进入自己系统的界面,并且不显示登录欢迎页面&#xf…