基于云环境中Docker容器的取证技术研究

2018-10-08 06:07李鹏超
西安邮电大学学报 2018年4期
关键词:镜像命名进程

李鹏超,路 斐,向 勇

(1.重庆警察学院,重庆401331; 2.重庆市公安局电子物证司法鉴定中心,重庆401331)

云计算是一种分布式计算技术,因其具有灵活的动态可扩展性和快速部署能力,在当今互联网服务中占据大量市场份额[1]。资源虚拟化技术作为云环境的重要组成部分,在部署基础设施服务时至关重要[2]。Docker是一种新型可移植虚拟化技术,能够提供更灵活快速的部署方案以及基于大型生态系统的快速软件开发能力,已广泛应用在云计算基础设施建设过程中[3]。目前,取证技术主要聚焦在普通主机或传统虚拟机环境,对Docker容器在事件分析和调查取证中并没有较为适用的技术手段,因此,本文拟在对Docker容器架构及组件研究的基础上,探讨基于Dcoker环境的数据取证技术。

1 Docker技术基础

Docker技术解决的核心问题是利用LXC实现类似虚拟机的功能,此技术可以更加合理的分配和利用软、硬件资源,为用户提供更加高性能的虚拟化环境。Docker是一种用于管理和部署软件容器的开源软件[4],其作为系统中独立运行环境,在使用单个公共内核时会将进程或进程组彼此隔离开来,这种隔离涉及进程空间的分离、进程间通信机制、网络资源使用、文件系统访问和资源利用和分配等。而Docker容器是基于Linux平台内核的控制组、命名空间和支持不同层的文件系统驱动程序实现了隔离。

1.1 容器和镜像

容器是一个镜像在运行时的实例化,而镜像是包含了创建一组指定特性进程所需要的所有必要数据和信息。例如,镜像包含有应用程序使用的端口信息,以及在实例化过程中应用到的程序。镜像除了内核使用系统调用接口和核心设备外,其它都是完全独立于主机系统上的实例化实现。在Docker环境下的所有实体(如容器、镜像以及网络字段)都被一个唯一标识符所标记称为ContainerID/IamgeID。然而该标识符由不同方式创建而成,IamgeID由部分镜像内容hash生成,而ContainerID是完全随机生成。

Docker镜像是由一系列只读层组成,每一层都能够为Docker容器提供不同类型的资源,当用户生成一个容器的时候,Docker会自行加载镜像中包含的所有只读层,并在最上层加入一个读写层,以达成镜像实例化容器的目的。这种设计方式使得Docker可以提高镜像构建效率和资源共享的最大化,节约部署虚拟环境的时间和存储空间。但是Docker容器的数据存储采用的分层技术,也给已删除文件的恢复和取证工作带来了新的挑战。

1.2 Cgroups控制组技术

Cgroups(Control groups)是Linux内核提供的一种高效的用户组管理机制,这种机制可以根据特定行为把一系列系统任务及其子任务整合到按资源划分等级不同的组内,系统按照分组级别的不同,有差别的进行资源管理。容器要实现虚拟化必须进行隔离,以保证资源的独立性,而Cgroups可以限制、记录、隔离进程组所使用的物理资源从而为资源的隔离提供基础保障,因此 Cgruops是构建Docker等一系列虚拟化管理工具的基石。Cgroups的主要作用是为不同用户层面的资源管理提供一个统一化接口以实现从单个进程的资源操控到系统层面的虚拟化。

Cgroups自身可以通过多种方式对资源进行控制,因此在对内容做取证分析时,技术人员需要注意容器可被一个或多个Cgroups关联复用问题。

1.3 Namespace 命名空间

为了实现在分布式的环境下进行通信和资源定位,Docker容器会使用另一种机制对系统资源进行隔离即命名空间机制。命名空间是一种隔离系统调用,其目的是在Linux内核中实现轻量级虚线化。在同一个Namespace下的进程可以感知彼此的变化而对同一命名空间以外的进程实现透明,类似于在一个独立的系统环境中以此实现独立和隔离的目的。例如,同一个文件系统装入点可以在不同的命名空间中使用。因此,Namespace的使用也给进程取证工作带来新问题。

1.4 分层文件系统

Docker与其他虚拟化技术一个显著的区别是其支持分层文件系统,例如AUFS等分层文件系统[4]。这些文件系统有一个共同的特点是基于文件系统驱动程序的分层结构,它提供了从不同层构建单个文件系统的可能,以便以统一和抽象的方式呈现给进程。如图1所示。

图1 Docker容器分层

Docker镜像由一层或多层文件系统组成,各层可以有不同来源,也可被不同用户创建。当容器被实例化时,创建一个读写层,该层被设置为顶层,容器中的所有写访问仅在这一层中执行,基础层作为只读层保持不变。因此,Docker容器这种分层存储数据的方式给数据取证带来一定的难度,也将成为本文取证技术研究的重点。

2 基于Docker容器的文件取证研究

Docker容器作为一种轻量级且具有分层结构的虚拟环境,在取证方法上与传统主机及虚拟环境取证存在一定的差异[5]。在Docker主机上进行取证分析时要考虑Docker容器的特殊性及具体细节,否则会造成取证内容的遗失和不完整。本文对在Docker主机中取证的各方面内容进行深入探讨,以实现对Docker主机更加全面的取证分析。

2.1 基于分层文件系统的数据恢复及归属性分析

Docker容器通过特定的文件系统驱动程序访问文件。Docker容器是基于分层文件系统结构实现对文件的管理,在对Docker容器中文件进行取证时,首要考虑分层文件系统对文件的管理方式。在Docker容器中隶属于不同层的文件具有不同的访问权限,因此在对Docker容器中存储的文件取证分析时要按层分别予以考虑。根据文件系统分层的原理,Docker镜像被存储在一系列的只读层,当开启一个容器系统会读取只读镜像并添加一个读写层在顶部。如果正在运行的容器修改了现有的文件,该文件将被拷贝出底层的只读层到最顶层的读写层,在读写层中的旧版本文件隐藏于该文件之下,但并没有被修改。因此,如果文件在Docker容器中被删除,则可能存在两种情况:(1)该文件来源于读写层。在这种情况下文件将随底层文件系统层上的正常操作系统机制一起删除。(2)该文件来源于镜像层。在此情况下,会在读写层中留下一个被删除文件的索引,但该文件仍然存在于镜像层之中。因此,文件存储的不同位置必须使用不同的方法来进行恢复。

2.1.1 恢复读写层的被删除文件方法

根据Docker容器中分层文件系统的管理机制,根据系统中读写层的特殊性,提出使用“文件雕复”的方式对已删除文件进行恢复。

“文件雕复”[6]是一种在文件卷、磁盘镜像或者文件中字符组合(如魔数)中进行线性搜索的方法。此方法在文件的系统元信息[7]不可信任或被损坏时可以恢复尚未被覆盖的已分配和被删除的文件,但碎片文件因其特殊性不可以被完整重建,使用“文件雕复”技术恢复的文件一般都不能完整恢复其元信息(如文件名,路径,时间戳或类内容)。这一限制使得在Docker环境下进行取证分析时,会遇到指定删除文件的归属问题。因为,“文件雕复”技术能够将不带有元数据的文件恢复到特定的容器,但是如何确定区分文件是否属于该Docker容器,则需要元数据才能确定。本文在结合分层文件系统特性的基础上对如何确定已恢复文件归属问题在后文予以分析。

另外,对Overlay2分层文件系统进行分析时发现,其使用了一个名为MountID的数据,经过研究发现可以利用MountID确定已恢复文件的归属问题。因为,容器的MountID在容器的配置文件/../config.v2.json中存储,且容器对应的读写层存储在$MountID中。同时,系统在容器的启动初始化期间会创建一个/../l$MountID-init目录,从而允许快速索引所有在相应宿主主机上生成的Docker容器的读写层。通过检索这个目录的方式可以确定读写层及保存文件的归属。而更深入的文件系统层存储在/../lower文件中以缩写的形式降序排列。在对Overlay2分层文件系统进一步分析发现,还可在/../$ContainerID下进一步取证分析Diff和Merge子文件夹。在Diff文件夹中包含读写层中创建且尚未删除的所有文件。在Merge文件夹包含整个Overlay2文件系统提供的所有文件系统层信息。结合两者信息后发现,当文件系统删除较低层提供的读写层中的文件时,系统会分配一个标记为Linux字符设备的ID,从而指示Overlay2忽略此文件以查看全局视图。因此,在较低层中删除的所有文件都可以通过命令进行标识,然后通过遍历分层并检查相应文件是否存在以进行检验及取证。

2.1.2 恢复只读层被删除文件方法

根据分层文件系统删除原理,当需要删除存在于只读层的文件时,系统将会在读写层的相应位置建立一个特殊的文件作为删除标记且该文件具有C属性。就是说删除操作成功完成之后,并不会造成只读层存储的文件发生任何变化。尽管最终的分层联合文件系统中可以看到这种删除动作造成的结果,但是在只读层仍然保留有源文件。所以,这也是分层文件系统所具备的一大优点即文件系统的隔离。因此,对在只读层被修改或删除的文件只需要在只读层对源文件进行提取和分析既可。

2.1.3 恢复已删除文件归属性分析

在Docker环境下进行取证分析时不但要考虑如何将分属于不同层次的已删除文件进行恢复,同时要思考恢复的文件归属于某个容器的问题。解决文件归属问题必须依赖于文件的元数据。元数据就是关于文件归属于容器某一层的额外信息,它不仅能够让Docker容器获取运行和构建时的信息,还可以对文件的归属进行确定。在Docker的只读层和读写层存储的文件均包含元数据。但利用“文件雕复”还原的文件通常缺少此类信息因而不可能进行有效的文件位置确定。只有当文件本身能够提供有关自身的上下文信息时才可与相应的容器或层级进行关联。要解决文件的来源问题,一种可行解决方案是利用排除法,首先排除所有由文件雕刻恢复的以文件分配表形式存储在文件系统中的文件,然后排除所有可以用文件系统自带的还原机制进行恢复的文件,最后确定其余文件所属容器。此外,还可以通过检查剩余的先前未知的已雕刻文件信息以确定数据块属于哪个容器。例如Ext文件系统分配的新文件恰好和目标文件在同一父目录同一属主下,那么就可以提供粗略的上下文信息。但是由于这些信息的不确定性,在取证调查过程中只能作为一种思路或参考。

在Docker容器中还可以利用恢复后的文件路径中包括的容器/镜像ID确定目标文件所属容器,已达到在取证分析时确定文件归属目的。

确定文件归属的前提是需知道一个镜像被哪些容器通过读写层使用。通过系统运行时信息和特定的配置文件,可以实现文件和容器之间的关联。文件和容器之间的关联是可能通过运行时信息和特定配置文件予以确定的。此外,确定文件是否来源于容器或镜像,此信息与在运行时分析文件的可见性有一定关系。根据现有Docker容器ID的确认方法[8],假设已经从容器中恢复了已删除的文件,文件的完整原始路径成为已知。以AUFS分层文件系统为例,在AUFS文件系统中容器的文件存储在/var/lib/docker/aufs路径下,考虑到已经恢复的文件可能来自不同的层,各自层可以在AufsID下发现/var/lib/docker/aufs/layers/$AufsID。所以,需要先从恢复路径中提取AufsID。若要更进一步推断涉及该AufsID的所有容器,则 ContainerID和/var/liib/Docker/image/aufs/layerdb文件都应挂载在$ContainerID/mountID且是可读的,通过匹配该文件中存储的ID和aufsid,如果匹配上,最初包含文件的容器就能够识别出来。

同样,如果可以识别出相应的Inode,就可以直接从包含原始文件的底层的目录中提取相应关联信息。

2.2 Docker容器的命名空间在取证中的作用

Docker容器所实现的隔离性主要来自内核的命名空间,因此,Linux内核中不同类型的命名空间会对取证分析产生不同的影响。由于UTS命名空间[8]允许配置特定于容器的时区,所以在容器的实时取证分析时必须考虑潜在的时间差异性。例如在分层文件系统中修改文件时始终使用主机系统的时间,并在运行时动态调整每个容器的时间戳。

在对PID命名空间[9]进行取证分析时,需要考虑主机上的进程和一个容器中的进程接收相同的进程PID问题。主机上的PID具有唯一性且与容器内的PID相同,在将PID应用于取证分析时,可以通过获取主机上PID的方式,确定容器中的进程归属。与PID命名空间类似,用户命名空间允许将用户UID或组GID从一个容器映射到主机上的另一个UID或GID。例如,一个进程可以在具有UID0的容器内运行,但主机上的相应进程却使用归属于另一个容器的UID2运行。就像在PID命名空间中一样,如果日志文件中包含UID会在分析时带来些挑战,因为这种情况系统可能需要通过修改/etc/subuid和/etc/subgid文件的方式实现将容器的UID/GID指派给主机的UID/GID,在对Docker容器的进程取证时应予以认真考虑。

3 基于Docker容器的取证流程分析

基于单个Docker容器取证分析的流程如下。

(1)利用Docker info命令提取Docker容器的基本信息如,ContainerID,Images数以及Server Version和分层文件系统类型等信息。

(2)对Images和Container中存储的文件进行调查取证。如果存储在其中的文件信息被删除,还要结合上文中提出的分层文件系统数据恢复技术和方法,对存储在不同层级中的文件进行恢复。

(3)对容器的数据卷[10]进行取证分析。如果在调查Image和Docker的文件系统后,发现文件不被保存的文件系统中,则需要对Docker容器创建的文件的数据卷进行调查取证。这样的数据卷保存有Docker容器间共享的数据,而且数据本身与Docker的删除与否无关,会一直保存有Imagie或文件系统中不存储的内容。因此,需要另外的提取和分析。

(4)对Docker容器的文件日志进行取证分析。必须分析日志以了解容器运行痕迹。容器可以通过配置时的“--log-driver”选项[11]来记录在运行期间输出的数据。如果没有单独的选项,则可以使用json-file日志驱动程序[12],在这种情况下,可以通过“dockerlogs容器名称”查看特定容器的日志内容[13]。Docker主机的取证流程如图2所示。

图2 Docker主机取证流程

4 结语

对Docker的基本技术进行分析和探讨,着重阐述与物理主机和传统虚拟化技术相比在对Docker环境下做取证和事件分析时需要考虑的情况,并分析了使用Docker容器时其分层文件系统以及命名空间对已删除文件分析和取证的影响,最终,制定了基于单个Docker主机的取证流程。

猜你喜欢
镜像命名进程
命名——助力有机化学的学习
镜像
债券市场对外开放的进程与展望
改革开放进程中的国际收支统计
镜像
有一种男人以“暖”命名
为一条河命名——在白河源
镜像
社会进程中的新闻学探寻
俄罗斯现代化进程的阻碍