李鹏超,周 凯
(1.重庆警察学院 信息安全系,重庆 401331;2.西南大学 计算机与信息科学学院,重庆 400715)
目前,虚拟化技术已广泛应用于服务器中,Docker虚拟化技术[1-3]因其提供了轻量化的虚拟环境,与其他虚拟化工具相比更具优越性.但Docker虚拟化技术使用过程中还有诸多问题需进一步解决[4].例如,当Docker环境遭受人为破坏或攻击时,取证人员所进行的基于Docker环境的数据调查取证问题,目前尚未见对Docker取证技术进行深入研究的报道.取证人员为了解在一个Docker主机上发生的真实情况,除利用现有的主机调查取证方法外,还需要一种基于Docker环境下的特殊化取证方法.因此,本文在对Dokcer原理及相关技术分析的基础上,提出一种基于Docker主机的调查取证模型,并根据该取证流程各环节中Docker主机所处的不同状态制定有针对性的数字取证方法.
图1为传统虚拟机与Docker对比的示意图.由图1可见,传统虚拟机宿主主机操作系统上层是管理程序,管理程序上层是客户操作系统,最后在客户操作系统上运行应用程序.而在Docker环境中,宿主主机操作系统上层为Docker引擎,Docker在引擎上构建一个相互隔离的容器,在容器内运行应用程序.
Docker与传统虚拟技术的区别为Docker上不安装客户操作系统,只设置服务器的程序和库,且Docker引擎共享宿主机操作系统资源[5].
Docker中的镜像可提供服务器所需的程序、可编译执行文件等所有文件系统资源.而容器是Docker由镜像构成的特定可运行隔离环境.镜像以分层的形式组成,根据不同存储数据和存储库的使用方式,构成镜像的方式也不同.如Docker可通过dockerfile文件生成镜像,dockerfile是一个可自动化生成镜像的文件.按照dockerfile的拟定规则创建文件后,在该文件所属的路径中通过“docker build-t khs/Whserver:v2.”命令编译并生成镜像.在Docker中以特定的镜像为对象组成一个容器,如图2所示.
图1 传统虚拟机与Docker对比示意图Fig.1 Schematic diagram of comparison between traditional virtual machine and Docker
图2 Docker分层结构Fig.2 Layered structure of Docker
容器中存储的数据会随着容器的消失一起被删除.而数据卷的存在与容器无直接关系,因此用户可将需永久保存的数据或与其他容器和主机需共享保存的数据存储在数据卷中.Docker也支持数据卷功能.数据卷是指在容器挂载的宿主主机文件系统上的目录或文件[3].配置容器时使用“-v主机内目录:容器内的目录”命令将主机内的相应路径作为数据卷并映射到容器目录内.在数据卷上保存的文件或目录并不是存储在容器内的文件系统中,而是直接保存在宿主主机的相应目录内,即在容器内的数据卷上接触到的行为与容器本身的文件存储没有关系.
通过“docker commit”命令将容器生成为镜像,但数据卷内的数据不包含在镜像中,数据卷中的文件和目录即使在容器被删除后也依然存在.此外,还可使用特定的容器作为数据卷,这种方式称为数据卷容器[6].数据卷容器先通过命名的容器挂载数据卷,然后其他容器通过挂载该容器实现数据共享.
Docker还支持多种网络配置模式,包括单主机内的跨容器网络模式和跨多主机间的网络模式.
1.4.1 单主机内容器间网络模式 当Docker进入安装时会在主机上创建一个名为docker0的虚拟网桥,该主机上启动的Docker会连接到虚拟网桥[7].主机上的所有容器都通过虚拟网桥连接在一个二层网络中,用户可以通过使用网桥连接网络命令“docker network create-d bridge网桥名”创建新的虚拟网络.此外,容器组成时指定了“-network=网络名称”选项,可将相应的容器连接到特定网络.虽然容器可同时连接多个网络,但容器仅能在网络内通信,不能跨网络通信.此外,还可以在容器组织中指定“-link容器或id:连接时使用的别称”,这样构成的网络在容器间不仅可以使用IP地址通信,而且还可以通过指定的别称进行通信.如果使用link选项,所有相关DNS的信息会反映在相关内容中,可用于调查取证.
1.4.2 多主机中容器组成的网络
1) Ambassador跨主机间容器通信技术.针对不同主机上的两个容器间通信,Docker通过Ambassador模式实现[8].图3为使用Ambassador模式实现两个不同主机上容器间的网络连接模型.
图3 Ambassador网络模式Fig.3 Network pattern of Ambassador
不同主机的容器建立连接还需借助socat程序将TCP连接传达到另一个容器,实现步骤如下:
① 主机A创建使用端口号x的服务端容器;
② 使用“docker run-d -link A: servercontainer -nameambassadorforserver -p端口(x): 端口(x)服务端ambassador”命令启动服务端Ambassador容器;
③ 在另一台客户端主机上使用“docker run -d-name ambassadorforclient -expose 端口(y)-e SERVER_PORT_TCP=tcp://A主机IP地址: 端口(x)服务端ambassador”命令,在客户端主机B上启动另一个客户端Ambassador容器;
④ 通过“-link客户端Ambassador容器: 别称”命令连接在主机B上的客户端容器.
通过以上4步可实现Docker间的Ambassador模式网络连接.
2) Overlay网络模式.Overlay网络是不同主机间容器实现通信的网络[9].Docker自带的Swarm是一种Docker集群的管理和编排模式[10].Swarm将在多个主机上创建容器并实现容器间的跨主机通信.集群分管理节点和工作节点两部分,一般的操作在管理节点上执行.Swarm模式运行步骤如下:
① 管理节点主机使用“docker swarm init -advertise -addr主机IP地址”命令初始化集群,节点间相互通信的IP地址为主机IP地址,默认端口为2377;
② 工作节点主机使用命令“docker swarm join -token 步骤①中使用的IP地址: 2377端口”加入到初始化的集群中;
③ Swarm集群组成后,管理节点主机使用“docker service create -name Websever -replicas 3 -publish 8080:80 Nginx”命令在Swarm集群中发布应用服务,并将容器中的80端口映射到Swarm集群的8080端口,此时Swarm内的节点中端口被公开,可通过Swarm技术操作提供服务.
通过上述方式Docker实现了在集群模式下的网络连接.
在对Docker进行调查取证时,可能会出现部署在Docker容器中的一个网站服务器受到恶意攻击的情形.例如,某企业为了提供服务,需要一个服务器提供全部周期更新的服务,该服务器可能受到攻击,使调查人员提取到可能出现恶性程序的镜像.此外,作为基础设施提供服务的主机自身也可能受到攻击.这种情形下,取证人员在进行取证过程中不仅要分析主机自身,还要调查提供服务的Docker环境.
在对Docker主机进行取证过程中,存在Docker守护进程启动或停止两种情形.前者可通过使用基本指令进行取证;后者如果允许重启Docker服务也可使用基本命令进行调查.但如果出现以下情形时,取证人员则需利用Docker相关的技术和方法提取证据:
1) 将Docker的宿主主机硬盘复制后,用克隆硬盘重新运行Docker服务,由于当时各服务的运行情形已不存在,因此需要对当时情形提供的信息进行调查取证;
2) 将特定容器文件系统中存储的已删除文件以传统取证工具恢复后进行调查取证;
3) 为取证先克隆宿主主机的文件系统,然后利用存在主机内的容器进行快速调查取证.
取证人员在调查取证过程中如果出现以上3种情形,就需要收集相关Docker服务留下的痕迹信息并掌握其含义.在调查取证过程中,取证人员不但要掌握使用Docker的主机及其间的网络信息,还要掌握各主机内容器的实际运行信息.本文针对Docker环境取证的特殊情形,有针对性地提出了Docker取证流程.无论Docker服务运行正常与否,取证人员对基础主机的Docker取证过程都如图4所示.
图4 基于Docker主机的取证流程Fig.4 Forensics process based on Docker host
取证人员在取证调查时,不但要了解多主机组成网络所提供的Docker服务,也要掌握在单一主机上运行的Docker所提供的服务.在前者情形下,取证人员先要掌握基础主机Docker间的网络结构,然后再进行单主机Docker的调查取证.
取证人员首先分析基于Docker网络间的连接方式.如果连接方式来自Overlay网络,则可在调查对象主机上利用“docker network”命令显示容器的Overlay网络ID,并分析相同Overlay网络其他主机内的容器是否属于同一网络.如果所有主机都是以Swarm模式进行网络连接,且在调查过程中使用“docker info”命令检测到Swarm的状态信息显示为Active,则在对Swarm模式分析时还要掌握该集群所提供的服务信息,因此需要查找管理节点,这是因为Swarm的信息查询命令只在管理节点有作用.在管理节点上以“docker service ls”命令显示在Swarm中执行的服务内容,并通过“docker service ps服务名”命令显示提供服务的进程列表.取证人员可以用“docker service inspect服务名”命令掌握该服务的详细内容.此外,取证人员也可以在管理节点上以“docker&ls”命令显示该Swarm内所有的目录状态并以“docker node inspect节点名称”命令显示特定节点的详细信息.因此,取证人员可通过执行上述命令,在Docker的网络环境中提取重要信息和证据.
如果取证人员所调查的Docker环境处于Inactive状态,则需要在“/var/lib/docker/container/”的目录内查询Config.v2.json文件以确定容器Overlay模式的网络信息.如果是Swarm模式,则需要确定主机所属Swarm执行的服务信息和应用程序.可以在主机的“/var/docker/swarm/docker-state.json”文件内查看管理节点、工作节点的本地IP地址及管理节点的远程IP地址信息.取证人员还可通过advertiseaddr命令监听IP地址和端口的状态,以获取Docker在Inactvie时的网络情形和信息.
取证人员在掌握了多主机间的网络连接信息后,即可进行单主机的Docker调查取证工作.
2.2.1 分析容器基本信息 取证人员需要收集相关主机内Docker容器的基本信息,以判断Docker的运行情形.取证人员可先通过“docker version”命令获取Docker的版本信息,然后使用“docker info”命令调查Docker上的容器数量、镜像数量、存储驱动程序、网络模式等基本信息,最后以“docker stats”命令获取各容器的主机资源使用信息.特别是在Docker服务Active的情形下“docker info”命令可以提供给取证人员关于Docker的整体信息.
2.2.2 主机内Docker网络调查取证 在单主机内也可以组成各容器间的网络连接,因此需要调查其网络状态.与多主机间的网络结构调查部分类似,取证人员先使用“docker network ls”命令列出网络结构包括跨Swarm多主机网络,然后利用“docker network inspect网络名”命令调查该网络的详细信息,最后得到在相关网络上连接的正在运行的容器相关信息.取证人员在取证过程中如果发现容器创建了一个网桥且挂载为docker0,则可进一步分析在网络上连接的容器功能.因此,取证人员需要利用“docker port”命令或“docker ps”命令掌握容器和主机的映射端口信息.
如果Docker的服务处于Inactive状态,则取证人员可在“/var/lib/docker/contaiers”目录内分析config.v2.json文件的相关信息.通过对config.v2.json文件内容进行分析可获取容器的bridge network信息,并知道该容器及其主机的端口状态.在同一路径的hosts文件内,容器建立时使用的“-link选项”提供了容器的相关信息,以“links: [连接容器名称: 指定别称]”形式存在.通过指定别称还可获取连接到其他容器的关键信息,所以取证人员可以此进行深入取证分析.
2.2.3 镜像及容器的调查取证 基于Docker的容器和镜像分析是Docker主机取证研究的核心部分.取证人员获取镜像和容器的状态信息后,与上文所获取的网络取证结果相结合,不仅能查明主机的作用而且可以在存储相关内容的文件系统中获得更直接的证据.
1) 镜像和容器基本信息调查.Docker在Active的情形下,取证人员可以使用“docker images”命令查询已存在的镜像信息,使用“docker ps”命令获取在激活状态下的容器信息.如果取证人员想查询主机上被指定的容器信息,可以使用“docker ps -a”命令.如果需要进一步收集各个镜像或容器的详细信息,则需要使用“docker inspect镜像或容器名”命令.
2) 特定容器的取证分析.在基于Docker主机的取证过程中关键是要掌握容器在执行时的服务信息.取证人员可利用“docker top”命令掌握特定容器内运行的进程信息,用“docker attach容器名”命令获取当前容器中输出的内容.为了检查在现有镜像上进行容器实例化后文件结构是否发生更改,取证人员可使用“docker diff 容器名”命令查看文件结构的更改信息,其中A表示增加,C表示变更,D表示被删除的文件或目录[11].如果在删除文件中发现需要深入分析的文件,则可使用“dockercopy 容器路径:容器名 主机路径”命令复制相应目录或文件到宿主主机后再进行分析.最后,取证人员还可通过调查容器内的进程和文件结构的变更事项,发现该容器的运行是否有异常.
3) 文件系统信息调查.在Docker服务Active的状态下,取证人员可对镜像或容器的文件系统以文件为单位进行提取分析.取证人员可利用“docker save -o文件名.tar镜像名”命令将特定的镜像提取成tar文件后,在其他主机的Docker中使用“docker load文件名.tar”命令将该镜像重新加载分析.如果把需要进一步调查的容器原样地提取,则需要使用“docker export容器名称>文件名.tar”命令,然后使用“cat文件名.tar|docker import-指定的名称”命令在本地重新生成容器.但即使将容器的文件系统重新装入到Docker内,在此状态下镜像内存在的被删除文件或容器形成后被删除文件仍然无法恢复.因此,为了恢复在特定容器内被删除的文件,取证人员需使用其他方法提取文件系统中被删除的文件信息.根据Docker使用存储驱动程序的不同恢复容器内被删除文件的方法有差异[12].
调查镜像和容器的文件系统后发现有些文件不被保存在相应的文件系统中,因此需进行对容器创建的数据卷进行调查.数据卷用于容器间的数据共享,其本身存储的信息与容器无关,因此对数据卷保存的信息需另外进行调查取证.在容器处于Active状态下,取证人员使用“docker volume ls”命令和“docker volume inspection卷名”命令可获得数据卷的信息.
如果取证人员需要在Docker处于Inactive状态中确认特定容器使用的数据卷文件,则可通过“/var/lib/docker/containers/”目录内config.v2.json文件中的sha256值确认容器名称,然后从同一文件内容中查询mount的sha256值即可获取要进一步分析的文件信息.此外,取证人员还可以从“/var/lib/docker/volumes/”中查看该容器在数据卷上留下的文件或目录.
关于容器内各种行为轨迹的信息调查,以时间为调查主线可获取更多的线索.因此,要了解各时间段在容器内的操作痕迹,必须分析其操作日志信息.容器在生成时以“-log-driver”选项指定了日志方式,记录了容器在运行过程输出的数据信息.取证人员可通过“docker logs容器名称”命令查看容器的日志信息.
如果容器处于Inactive状态,则可以通过查询“/var/lib/docker/containers/container-jsonlog”命令获取相关的日志信息.如果登录驱动程序不是默认选项,而是被指定为另一个主机,则被指定容器的“docker logs”无法使用,要调查登录另一个主机.日志驱动程序选项“gelf,fluentd,awslogs,splunk,etwlogs,gcplogs”可作为外部主机传送的选项[13-14].在此情形下,取证人员需掌握登录主机的位置和运行原理提取该容器的日志.由于日志对容器具有标准输入输出记录,因此可通过日志调查该系统的系统管理器在容器内部进行的活动,得到关于一个恶意行为以及应用程序发生错误的相关线索.
综上所述,本文以Docker容器的数据存储原理和网络环境分析为基础,针对Docker作为服务环境的主机在受到恶意攻击或破坏时,取证人员应以何种角度进行取证进行了研究.通过建立切实有效的取证模型和工作流程,阐述了在Docker守护进程处于活动时,取证人员可根据取证模型并通过使用Docker守护进程的相关命令完成对Docker的调查取证工作.