【openvpn】TAP模式

news2024/11/19 19:20:57

TAP与TUN模式简介

在OpenVPN中有两种工作模式,一种称为 TUN(tunnel)模式,即通道的意思;另一种是TAP(Terminal Access Point)模式,即一种网络设备或软件虚拟设备的意思。

TUN模式是一种虚拟点对点的网络设备模式。通常用于实现点对点(即主机到主机)虚拟专用网络(VPN)。在TUN模式下,OpenVPN会创建一个虚拟网络接口(通常称为tun0),通过该接口发送和接收IP包。TUN模式通常用于路由网络流量,因此其只能够处理IP层(OSI模型中的第3层)数据包,不能处理链路层(OSI模型中的第2层)数据包。

TAP模式是一种以太网桥设备模式。通常用于实现一点对多点(即主机到局域网)虚拟专用网络(VPN)。在TAP模式下,OpenVPN同样会创建一个虚拟网络接口(通常称为tap0),不过该接口与NAT模式下的接口不同,它可以接收和发送以太网帧,就像一个物理的以太网接口一样。TAP模式可以处理链路层数据包,因此它可以传输多种类型的网络包,如IP、ARP、NetBIOS等。

一般来说,TUN模式更适合用于远程访问,因为它可以更好地控制网络流量,并且可以提供更好的性能。而TAP模式更适合用于网络扩展,因为它可以模拟真实的局域网,并且可以传输多种类型的网络包

tap模式下的OpenVPN节点可以被看作一个虚拟的以太网,节点之间的通信可以通过以太网协议来完成;

tun模式是三层模式,也就是说,tun模式下的OpenVPN节点可以被看作一个虚拟的IP网络,节点之间的通信完全靠路由来完成;

如此,OpenVPN可以既是以太网模型又可以是IP网络模型,但是同一时间只能是一种。那么在每一种模型下,OpenVPN就扮演了该网络模型的核心设备的角色,对于以太网,它是交换机,对于IP网络,它是路由器,当然这种设备是虚拟出来的,是软件实现,是由OpenVPN的代码实现的。前文总是说OpenVPN是一个虚拟的交换机,又说OpenVPN是一个虚拟的路由器,那么它到底如何做到的的呢?

TAP模式实现原理

以太网交换机内部有一个简单的映射表,映射MAC地址和端口信息。注意,这个映射表的容量是有限的,这也常常成为一种攻击向量…(注意,最美丽的天使是断了翅膀再也回不了天国的天使),只要有数据帧经过交换机,哪怕是一个广播,交换机就记录下该数据帧的源地址和进入的端口,将之做成一个映射项,存入这个以太网交换机的“路由表”,隔一段时间,这个映射会失效。以上就是以太网的简单的“路由表维护机制”。

在OpenVPN中,如果它真的要实现一个虚拟的以太网交换机,那么它就应该实现一个类似的路由表,保存MAC地址和端口的映射项。在OpenVPN中,其实并不存在真正的“端口”,所谓的端口都是虚拟出来的,在OpenVPN中表现为一个结构体multi_instance,所谓的MAC地址还是MAC,这个并没有变。那么在OpenVPN中,如果想实现一个虚拟的交换机,那么就是要实现一个MAC地址和multi_instance的映射表,对于映射表之类的,用软件实现要比用硬件实现简单得多,C语言可以很简单的实现类似table,hash之类的数据结构。

由于tap模式下,所有的VPN节点构成了一个虚拟的以太网,那么这个虚拟的交换机的MAC地址-multi_instance映射表就要起码包容所有的这些VPN节点,至于是否要包容其它的MAC地址,那就看你的网络拓扑了,基本上tap模式下的拓扑有三类:

全网桥接

这种拓扑几乎不用任何路由,整个网络都是桥接的,拓扑图如下:

这样子,OpenVPN虚拟出来的交换机就和各个VPN网段内部的物理交换机是完全并列的关系。这种拓扑下,OpenVPN的虚拟交换机需要学习所有VPN节点后面物理网段的所有的主机的MAC地址信息。

仅VPN节点桥接,其它路由

这种拓扑最简单。只需要考虑接入的VPN节点即可。拓扑图如下:

这样子,OpenVPN虚拟交换机只需要学习VPN节点的MAC地址即可。

一些VPN节点桥接,另一些路由 

这种拓扑其实上上述两种的综合。拓扑图就不再画了吧。 这样子,OpenVPN虚拟交换机需要学习的MAC地址信息完全取决于各个VPN节点所在的主机是怎么配置的。

理解了上述的拓扑,继续下去就简单了。我们知道在OpenVPN中有一个multi.c文件,里面有一个multi_process_incoming_link函数,该函数中有两个逻辑,其中之一是处理TUN模式的逻辑,这个一会儿再说,另一个就是处理TAP模式,这个正是我们现在要分析的。该函数处理网络上过来的使用OpenVPN协议封装的加密流量,将之解密,然后写入到虚拟网卡或者经由其它multi_instance加密发送给其它的OpenVPN客户端。

在分析代码之前,首先要明白的是,对于TAP模式,OpenVPN实现的虚拟设备主要处理虚拟交换机的MAC-“端口(multi_instance)”映射,而对于TUN模式,OpenVPN主要处理路由缓存,其实就是内部路由所体现的一张虚拟的路由表。不管是tap模式还是tun模式,路由信息都是保存在一个hash表中的,在OpenVPN的server模式中,这个hash表为multi_context的vhash字段。在multi_process_incoming_link中,处理TAP模式的逻辑如下(不考虑内部包过滤):

else if (TUNNEL_TYPE (m->top.c1.tuntap) == DEV_TYPE_TAP) {
    //从解密后的载荷包中解析中源MAC地址和目标MAC地址
    mroute_flags = mroute_extract_addr_from_packet (&src,
                            &dest,
                            NULL,
                            NULL,
                            &c->c2.to_tun,
                            DEV_TYPE_TAP);
    if (mroute_flags & MROUTE_EXTRACT_SUCCEEDED) {
        //虚拟交换机的学习,和物理交换机的学习机制一样
        if (multi_learn_addr (m, m->pending, &src, 0) == m->pending) {
            if (m->enable_c2c) {
                if (mroute_flags & (需要广播的标识)) {
                    multi_bcast (m, &c->c2.to_tun, m->pending, NULL);
                } else {
                    mi = multi_get_instance_by_virtual_addr (m, &dest, false);
                  /* 如果目的地址对应另外一个multi_instance,那么就直接将数据“路由”到该客户端,不再往虚拟网卡中写  */
                    if (mi) {
                        multi_unicast (m, &c->c2.to_tun, mi);
                        register_activity (c, BLEN(&c->c2.to_tun));
                        c->c2.to_tun.len = 0;
                    }
                }
            }
        } else {
            msg (bad source address);
            c->c2.to_tun.len = 0;
        }
    } else {
        c->c2.to_tun.len = 0;
    }
}

 在mroute_extract_addr_from_packet中解析出该数据包的目的地址(此时数据包已经被解密了),将其保存到dest变量,接下来就要地址学习了,和物理交换机一样,此时虚拟交换机学习的是发送该数据包的源地址,所谓的学习过程很简单:

  1. 在vhash中查找这个src,如果没有找到则添加,同时和该src的multi_instance关联;
  2. 在vhash中查找这个src,如果找到了,则更新vhash的对应项。 在地址学习之后,接下来调用multi_get_instance_by_virtual_addr试图找到目的地址对应的multi_instance,注意,这个对应关系也是虚拟交换机学习得到的,在multi_get_instance_by_virtual_addr函数中,实际上是在同一个vhash中进行查找的,就是刚才虚拟交换机地址学习时更新的那个vhash。如果找到了,则直接将数据包路由给对应的multi_instance,也就不再往虚拟网卡中写了,否则就写入虚拟网卡。

值得注意的是,前一段的一句话“如果找到了,则直接将数据包路由给对应的multi_instance”,为什么不是“对应的OpenVPN客户端”而是“对应的multi_instance”呢?这是因为在tap模式下,如果有虚拟网卡和物理网卡桥接的情况,那么实际上OpenVPN节点后面的节点也处于同一个虚拟以太网中,此时对应的目的地址就不再是OpenVPN客户端本身了,而是该OpenVPN客户端后面的一台主机。在tap模式下,主要有两个函数调用值得注意,一个是multi_learn_addr,另一个是multi_get_instance_by_virtual_addr,前者学习MAC地址和multi_instance的映射,以src作为输入,后者根据学者学习的结果,从OpenVPN的虚拟交换机的映射表中取出和dest对应的multi_instance,以dest作为输入,learn函数将一个项插入这个映射表,而get函数则试图从这个表中取出一项,其实就是查表的过程。

TAP模式配置

dev tun:工作在tun模式

dev tap:工作在TAP模式

 

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

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

相关文章

即视角|出海正当时:欧美、东南亚、中东、拉美市场观察

即视角 Insight 共享即构新洞察,共建行业新动能——ZEGO即构科技基于音视频技术领域的多年深耕,综合面向各行业的服务经验,推出【即视角】栏目,发布即构对行业的洞察。欢迎大家探讨论道,共驱前行。 https://v.douyin…

【Note9】

9.PECI(Platform Environment Control Interface):peci是 intel提供的私有协议,openbmc是由intel授权的,其他不授权是不能用。硬件上是一根线,不像i2c是2根线 11.1 模式和命令介绍:peci1.1只支…

华为OD机试之拔河比赛(Java源码)

文章目录 拔河比赛题目描述输入描述输出描述示例代码 拔河比赛 题目描述 公司最近准备进行拔河比赛,需要在全部员工中进行挑选。 选拔的规则如下: 按照身高优先、体重次优先的方式准备比赛阵容;规定参赛的队伍派出10名选手。 请实现一个选…

Imagination如何引领更安全的汽车行业?

如果您想购买一款全新的车辆,它很有可能配备数字显示屏,为用户体验提供丰富的驾驶体验,并可自由设置显示。想要更动感的仪表盘?那也没问题,只需改变驾驶主题。亦或是把音乐放在居中位置,同时在另一个屏幕上…

兼容性测试可否提高用户满意度?

兼容性测试可否提高用户满意度? 在信息化时代,软件应用的兼容性一直是一个重要的问题。由于操作系统版本、硬件设备、浏览器等因素的差异,软件在不同环境下运行的稳定性和表现也会不同。因此,如果对软件在不同的环境下进行兼容性测试&#x…

qt信号槽

目录 自定义信号槽 所谓信号槽,实际就是观察者模式 (发布 - 订阅模式)。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如…

springboot实验室管理系统-计算机毕设 附源码86757

springboot实验室管理系统 摘 要 验室管理系统是将实验室的分析仪器通过计算机网络连起来,采用科学的管理思想和先进的数据库技术,实现以实验室为核心的整体环境的全方位管理。它集用户管理,实验室信息管理,实验室预约管理&#x…

【历史上的今天】6 月 21 日:第一台存储程序计算机首次运行;XML 之父诞生;IBM 推出 AS/400

整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来。 今天是 2023 年 6 月 21 日,在 23 年前的今天,中国联通公司在香港、纽约成功上市,筹资 56.5 亿美元,进入全球首次股票公开发行史…

LeetCode - #86 分隔链表

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 我们社区陆续会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。)的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新…

Cortext-M3系列:M3的底层编程(7)

1、概览 在CM3上编程,既可以使用C也可以使用汇编,keil也支持C,但是大多数人还是会在C与汇编。C与汇编都“尺有所短,寸有所长”,不能互相取代。使用C能开发大型程序,而汇编则用于执行特种任务。 1.1 使用汇…

去中心化金融(DeFi)的发展历史

随着Web3.0的兴起,去中心化金融(Decentralized Finance,DeFi)正逐渐成为金融领域的热门话题。DeFi旨在通过区块链技术和智能合约,实现无需信任的金融交易和服务,摆脱传统金融中心化的限制。然而&#xff0c…

C# Winform Label 控件

目录 一、概述 二、基本用法 1.控件内容显示 2.控件的外观 3.自定义控件的大小 4.控件的内边距 5.设置文本的固定位置 6.控件的事件 结束 一、概述 Label 控件是 winform 开发中最常用的一个控件,一般用做显示文本,也有时用做打开链接等操作。…

如何解决无法直接启动带有“类库输出类型”的项目

输出类型为类库的项目是编译为 dll 文件的项目,该文件旨在供其他项目使用。它无法直接启动,因为它没有 exe 文件。若要调试此项目,请在此解决方案中添加一个引用库项目的可执行项目。将这个可执行项目设置为启动项目,如下&#xf…

msp430fr2155 在线升级(一)

前言:由于单片机如果不支持USB等方式在线升级,每次升级会设计拆机升级单片机,这对于一个成熟的产品是很鸡肋的。所以记录一下本次研发升级功能的过程以及所需要的问题。 一、升级程序设计 二、内存重新分配 1.芯片原有内存分配 原有内存分…

做电商服务软件(电商ERP),怎么实现与电商平台的数据交互?

电商领域是目前互联网最热门、最活跃的行业之一,随着消费需求的增长和普及化,用户对于商品种类和购物体验的要求也越来越高,精准、高效、快速成为谋求更大商品销量的共同目标。因此,电商服务软件的市场需求正不断增强。 想要开发一…

C++---虚函数(8)

多态 虚函数 虚函数就是在类的成员函数声明前加virtual,该成员函数就变成了虚函数。一旦一个类中有虚函数,编译器就会为该类生成虚函数表。 虚函数表中一个元素记录一个虚函数的地址,使用该类构造对象时,对象前4(8)个字节记录虚…

团队知识库的使用场景有哪些?如何搭建团队知识库?

团队知识库是一种用于共享和管理团队知识和信息的工具。它可以帮助团队成员更好地组织、存储、查找和分享信息,提高工作效率和准确性。以下是团队知识库的使用场景和搭建方法的详细介绍。 一、团队知识库的使用场景 项目管理 团队知识库可以帮助团队成员更好地管…

封神之后,又来超神?南卡OE骨传导开放式耳机有啥新本领

终于到了适合夜跑的温度,我的新跑鞋和专用陪跑运动耳机也都收到了,万事俱备却意外中招“二阳”了。虽然身体情况,短期是不能支持去跑步运动了,但每天戴着新耳机打打王者也还是一样很欢乐的。 反正现在时间很多很闲,我…

pyqt6安装与配置(基于vscode环境)

一、安装pyqt6和pyqt6-tools包 注意:pyqt6-tools目前仅支持python3.9版本,3.9版本后的安装部成功。(截止2022.11.20) 1.1 安装pyqt6和pyqt6-tools 安装pyqt和pyqt6-tools可以使用conda和pip进行安装 (1&#xff09…

基于高通camera-帧率-曝光

前人种树,后人乘凉;创造不易,请勿迁移~ daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 daisy.skye擅长嵌入式,Qt,Linux,等方面的知识 https://blog.csdn.net/qq_40715266?typelately ———————————————— 版权声明&…