APP下载

基于KVM的持续性数据保护设计与研究

2022-06-16龙星澧黄传波胡晓勤

现代计算机 2022年7期
关键词:调用磁盘数据保护

龙星澧,黄传波,胡晓勤

(1.四川大学网络空间安全学院,成都 610065;2.成都云祺科技有限公司,成都 610041)

0 引言

随着云计算技术高速发展和企业信息化的不断加速,数据安全逐渐成为大家越来越关注的内容,而容灾备份作为保障数据安全的一个重要方式,也越来越受到重视。

持续性数据保护技术(Continuous Data Protection,CDP)是近年来容灾备份领域提出的一个全新概念。传统数据保护方式一般为定时或手动备份,当数据发生损坏时,该方式只能恢复到数据备份的时间点,而这期间的数据则会发生丢失。采用持续性数据保护技术,则能连续捕获并保存数据的变化,在数据发生损坏时,其恢复目标点可以是任意时间,所以不会丢失数据。

服务器虚拟化技术是云计算中最核心的技术,基于内核的虚拟机(Kernel-Based Virtual Machine,KVM)是云计算中常用虚拟化技术,这是一种内建于Linux 系统的开源虚拟化技术解决方案。本文针对KVM 虚拟化技术,提出了一种持续性数据保护方法,其能在KVM 虚拟机运行期间,连续地捕获KVM 虚拟机产生的数据,实现持续性数据保护。

1 持续性数据保护方案设计

常用的KVM 虚拟化分为KVM 部分与QEMU部分,KVM 部分通过KVM.ko 这个内核模块来实现核心虚拟化的功能,也就是CPU 和内存的虚拟化;而QEMU 部分则提供了包括网卡在内的其他硬件的虚拟化,其运行在用户态,作为一个应用程序存在。两个部分互相协作,形成一套完整的虚拟化技术。

当KVM 虚拟化的guest 机要发起IO 请求时,guest 机首先会将指令发送给内核中的KVM 内核模块,KVM 内核模块对指令进行相应处理后,会发送数据给应用层的QEMU,QEMU 进行处理后,在宿主机上完成最后的IO 操作。具体的流程如图1所示。

图1 KVM虚拟机架构

由于KVM 虚拟机的IO 都是通过QEMU 执行的,所以要对KVM 进行持续性数据捕获,就需要捕获应用程序QEMU 的IO。本文采用了Linux Hook 技术编写IO 过滤驱动,对KVM 虚拟机数据进行捕获。

常见的Linux Hook 技术分为ring0 层Hook 和ring3 层Hook,其中ring0 层Hook 主要针对Linux系统内核,通过编写内核模块替换系统调用以及内核函数来实现Hook。ring3 层hook 被分为了动态注入和静态注入,静态注入为程序还没运行时,修改替换程序的.so 文件实现;而动态注入则需要在程序运行时,动态地将函数地址替换为我们所需要的函数。

QEMU 在Linux 中采用的是Linux 标准IO 流程,其过程如图2所示。

图2 Linux IO流程

编写IO 过滤驱动,首先需要确定过滤驱动的插入层次,常见过滤驱动一般在系统调用层、虚拟文件系统层或通用块层编写。

本文选取在系统调用层和应用层分别编写IO过滤驱动,以实现截获KVM虚拟机的IO。

要实现系统调用替换,首先通过Linux 内核导出函数kallsyms_lookup_name()获取系统调用表,接着替换掉系统调用表中的目标系统调用函数,最后在替换函数中执行完相关逻辑,并再调用原系统调用函数,保证系统正常运作。

本文所设计持续性数据保护系统架构如图3所示。

图3 持续性数据保护架构

2 模块设计

KVM 虚拟机支持多种不同的磁盘格式,如raw、qcow2 以及ceph 格式,不同的磁盘格式有不同的元数据用以描述数据的储存方式,在捕获数据IO的同时进行备份并不需要这些元数据。故针对不同格式的磁盘,需要设计不同的hook模块,过滤不同磁盘格式下的元数据。

2.1 raw格式磁盘Hook模块设计

Raw 格式为磁盘原生格式,可以直接挂载在不同的虚拟机中,没有额外元数据需要处理。直接捕获其IO 数据即可。整个过滤驱动运行流程如图4所示。

图4 raw格式磁盘Hook模块运行流程

如图4 所示,当QEMU 产生了IO 请求时,首先会通过IO 过滤驱动,由过滤驱动判断是否是目标磁盘文件,若为目标文件,则通过数据传输模块将IO 数据传到远端数据备份服务器进行备份,之后将参数传回原系统调用函数进行正常写入操作。

2.2 qcow2格式磁盘Hook模块设计

对qcow2磁盘进行数据捕获操作时,需要对元数据进行过滤操作,只保存实际数据。

qcow2 磁盘开头是一个固定存放在文件头的结构体,这个结构体描述了该qcow2文件的一些相关信息,结构体代码如下。

typedef struct QCowHeader{

uint32_t magic;

uint32_t version;

uint64_t backing_file_offset;

uint32_t backing_file_size;

uint32_t cluster_bits;

uint64_t size;/*in bytes*/

uint32_t crypt_method;

uint32_t l1_size;

uint64_t l1_table_offset;

uint64_t refcount_table_offset;

uint32_t refcount_table_clusters;

uint32_t nb_snapshots;

uint64_t snapshots_offset;

}QCowHeader;

其中,需要关注的是l1_size、l1_table_offset以及cluster_bits 这几项,l1_size是指l1table的大小,l1_table_offset 是l1 表在文件中的偏移,而cluster bits 则是用来计算qcow2 格式的一个cluster的大小,计算方法为1<

l1 表和l2 表是一个二级表项的储存结构,其中储存的是raw 磁盘格式道qocw2 磁盘格式的偏移信息。l1表的大小不固定,随着qcow2文件增长而增长,其中每个表项长度为8个字节,而l2 表固定为一个cluster 大小,其中每个表项为8个字节,一个qcow2 只能有一个有效的l1table,但是同时拥有多个l2table。l1table的第一项指向qcow2 文件中的第一个l2table 项,而第一个l2table 的第一项所指向的那个cluster,在转换成raw 格式后,其就是raw 格式的第一个cluster。所以,根据此二级表项,便可将qcow2格式动态转化为raw 格式数据,整个qcow2 磁盘数据捕获具体流程如图5所示。

图5 qcow2格式磁盘Hook模块运行流程

模块加载时,首先会读取磁盘文件中的元数据信息,根据元数据信息解析l1table 和l2table,并等待数据下发。当有针对目标文件写IO 到达时,首先根据解析出来的数据判断是否是元数据,若为元数据,直接下发IO,并重新解析l1table和l2table,重新解析两个表是因为如果写入数据是元数据,则有可能改变l1table 和l2table 内容。若非元数据,则先将数据写入备份文件,之后将IO下发到目标文件。

2.3 ceph格式磁盘Hook模块设计

KVM+ceph 是当前云环境下的常用组合,作为一款分布式文件系统,ceph在云环境中相对于传统文件系统能够发挥出更好的性能。

KVM 虚拟机使用ceph 作为储存,主要是用到librbd调用的ceph的IO接口,librbd是ceph基于librados的一个用户态接口,当我们在KVM中通过QEMU使用ceph文件系统时,QEMU通过librbd.so文件调用接口进行IO,所以其数据我们无法通过系统调用进行hook,想要获取ceph储存的IO数据,需要在应用层进行hook操作。

在应用层的hook 通常是指PLT/GOT hook,也就是对程序的got 表进行替换。PLT(Problogcedure Linkage Table)和GOT(Global Offset Table)是GCC 中生成shared library 的重要元素。Linux 对外部函数的引用是采用动态链接的,也就是说,只有在用到某个函数时,才会具体定位其在内存中的位置。

对于正在运行的程序,可以通过修改.got.plt 表将目标函数地址改为hook 函数的地址,实现对函数的hook,若程序还未运行,则可通过LD_PRELOAD 环境变量,直接将目标so 文件替换为hook所需的so文件。

针对ceph文件系统的IO函数Hook具体过程如图6所示。

图6 ceph磁盘Hook模块运行流程

如图6所示,首先程序会判断kvm 虚拟机是否启动,若未启动,则通过LD_PRELOAD 环境变量,让kvm 启动时自动加载hook 所需的so 文件,程序启动后,so 文件的代码会自动替换qemu 中关于ceph 的IO 函数。若KVM 虚拟机已启动,则需要首先调用程序libc 库中dlopen 函数,将hook 所需so 文件载入内存,之后通过Linux 的proc 文件系统修改进程内存,将.got.plt表中的目标函数地址修改为hook 函数地址,实现对数据的捕获。

2.4 数据恢复模块设计

针对数据恢复,本文设计了两种恢复模式。第一种为数据卷恢复模式,即当数据卷出现损坏或误操作时,将数据恢复到最初的数据卷状态,此时恢复模块会直接读取备份库中的数据卷快照文件,将数据卷恢复到最初状态。第二种则为目标点恢复模式,首先,在IO 数据备份时,系统会按照时间顺序将IO 数据进行排序,当用户指定一个恢复的时间点后,恢复模块会通过原始磁盘镜像以及备份库中所储存的IO 数据,按时间顺序对磁盘进行IO 重放,直到恢复到目标时间点为止。由此实现恢复到任意时间点的目标。

3 实验

本文测试系统由一台测试服务器和一台备份服务器组成,测试服务器用于运行KVM 虚拟机,备份服务器用于保存以及读取数据捕获模块所捕获的数据。

实验首先随机产生一个数据文件,计算文件MD5 码并进行保存,之后在测试服务器上开启KVM 虚拟机,分别使用raw、qcow2 以及ceph格式作为测试磁盘,将产生的数据文件写入测试磁盘,然后对磁盘进行格式化操作。最后,在使用恢复模块将磁盘恢复到数据格式化前,计算出恢复数据文件MD5 码,若MD5 码不变,则证明本文所设计系统能够正确保护数据。实验结果见表1。

表1 实验结果

实验结果表明,本文提出的持续性数据保护方法能够正确地对不同格式磁盘数据进行保护。

4 结语

针对KVM 虚拟机数据备份,本文提出了一种KVM 虚拟机数据持续性保护的设计以及开发思路,通过在应用层和内核层编写Hook 函数,实现了对KVM虚拟机IO的数据捕获,并通过IO重放的机制,将数据恢复到任意时间点,该设计具有一定的创新型,为KVM 虚拟机的数据保护提供了一种全新的思路。但目前针对不同的磁盘格式IO 捕获,仍存在适配性问题,下一步工作将针对此问题做进一步研究,以适应更多的磁盘格式。

猜你喜欢

调用磁盘数据保护
它的好 它的坏 详解动态磁盘
解决Windows磁盘签名冲突
欧盟最严数据保护条例生效 违反将严惩不贷
欧盟“最严”数据保护条例生效
未成年人能不能上社交网络
Windows系统下动态磁盘卷的分析与研究
基于Android Broadcast的短信安全监听系统的设计和实现
克隆硬盘很简单
利用RFC技术实现SAP系统接口通信
C++语言中函数参数传递方式剖析