我最近与Docker专家讨论了Docker与虚拟机的安全性。当我告诉我从不同来源获悉,在Docker容器中运行的代码要比从虚拟机中运行的代码容易逃脱时,专家解释说我是完全错误的,并且Docker机器与防止虚拟机或裸机相比,在防止恶意代码影响其他机器方面实际上更加安全。 。

据我了解,“ OS级虚拟化可重用虚拟机之间的内核空间”,如本网站的另一个答案所述。换句话说,来自Docker容器的代码可能会利用内核漏洞,而这是无法从虚拟机上实现的。 VMs或裸机隔离,在容器/机器中运行的代码会故意试图逃逸并感染/损坏其他容器/机器的情况下?假设Docker配置正确,可以防止此处描述的四种攻击中的三种。

评论

我一直认为Docker介于完整VM和直接在主机OS上运行代码之间的中间位置-您可以交换安全性以提高性能和灵活性。这就是为什么尽管有炒作,我还是让我的团队远离了它,至少直到技术成熟为止。

Docker的一个可能的次要安全优势:理想情况下,容器中应该只有很少的可执行文件/服务。容器甚至可能缺少外壳。这可以大大减少攻击面,尤其是对于依靠欺骗应用程序以运行其他可执行文件的攻击媒介而言。显然,这在VM中也是可能的,但是在实践中,那些倾向于使用诸如Chef / Puppet之类的配置管理工具,这反过来又意味着您通常也安装了软件包管理工具,常用的* nix实用程序等。

自称是任何技术专家的人可能会自觉或不自觉地偏向于该技术。仅仅花费大量时间来学习某些东西,可能会使人们更满意地看到某些东西。

这个Docker专家是在Docker工作的人还是仅仅是熟悉该技术的人?

@ToddWilcox“如果遇到佛陀,请杀死他。” –林吉

#1 楼

不,Docker容器并不比VM更安全。

引用Daniel Shapira:


仅在2017年,就发现了434个Linux内核漏洞,在这篇文章中已经看到,内核漏洞对于容器化环境可能是毁灭性的。这是因为容器与主机共享同一内核,因此仅依靠内置保护机制是不够的。


1。来自容器的内核漏洞利用

如果有人利用了容器内部的内核错误,他们就会在主机OS上利用它。如果此漏洞利用允许执行代码,它将在主机OS上执行,而不是在容器内部执行。

如果此漏洞利用允许任意的内存访问,则攻击者可以更改或读取任何其他数据容器。

在VM上,过程较长:攻击者必须同时利用VM内核,系统管理程序和主机内核(这可能与VM内核不同) 。

2。资源匮乏

由于所有容器共享相同的内核和相同的资源,因此,如果不限制对某些资源的访问,则一个容器可以用尽所有资源,从而使主机OS和其他容器饥饿。

在VM上,资源是由管理程序定义的,因此任何VM都不能拒绝任何资源的主机OS,因为可以将管理程序本身配置为限制使用资源。

3。容器突破

如果容器内的任何用户能够使用某种利用或错误配置逃脱该容器,他们将有权访问主机上运行的所有容器。发生这种情况是因为运行Docker引擎的用户是运行容器的用户。如果任何漏洞利用程序在主机上执行代码,它将在docker引擎的特权下执行,因此它可以访问任何容器。

4。数据分离

在Docker容器上,有一些未命名空间的资源:


SELinux
Cgroups
/sys/proc/sys

/proc/sysrq-trigger/proc/irq/proc/bus



/dev/mem/dev/sd*文件系统
内核模块>如果任何攻击者都可以利用这些元素中的任何一个,那么他们将拥有主机操作系统。

VM OS将无法直接访问这些元素中的任何一个。它将与管理程序进行对话,管理程序将对主机OS进行适当的系统调用。它将过滤掉无效的呼叫,从而增加一层安全性。

5。原始套接字

如果未正确固定,则默认Docker Unix套接字(/var/run/docker.sock)可以由任何容器安装。如果某些容器安装了该套接字,则它可以关闭,启动或创建新映像。它将小于正确配置的VM。无论使用多少加固工具,VM始终将更加安全。裸机隔离甚至比VM更安全。某些裸机实现(例如IBM PR / SM)可以保证分区就像在单独的硬件上一样分离。据我所知,无法逃避PR / SM虚拟化。

评论


总的来说,由于攻击面较小,我同意VM更有可能是安全的,但是,关于第1点,实际上,VM逃脱者不必利用VM内核,它们倾向于攻击设备驱动程序,由管理程序提供,攻击链可能非常简单。例如,会利用软盘驱动程序并允许VM逃逸的毒液。

–罗里·麦库恩(Rory McCune)
17年9月18日在10:02

我认为#5在那里很奇怪。在他们的头脑中没有人会将他们的/var/run/docker.sock转发到不受信任的容器,就像在他们的头脑中没有人将其VM Hypervisor API端点路由到不受信任的VM或以Xen dom0运行不受信任的内核一样。能够在VM中运行管理应用程序也是VM可以完成的功能。我说的是,软件不是白痴的解决方法。

– Lie Ryan
17年9月18日在16:50

这些日子之一,人们将学习...安全没有万灵丹。虚拟机,容器,微服务,整体设备,防火墙,气隙,磁通电容器都无关紧要。无论您使用什么工具,都需要继续做出明智的,具有安全意识的决策。可以通过在监视器上贴上一个便条纸来撤消世界上最大的防火墙,也可以通过在后台哭泣的婴儿同情愚蠢的服务台员工来撤消防火墙。没有一种技术可以使一种技术比另一种技术更安全。那么,让我们回到成为聪明,安全意识强的人吧?

– corsiKa
17年9月18日在18:54

@LieRyan:失去这个行业的人不是正确的想法

–石油
17年9月18日在19:04



@corsiKa:他们不会学习,因为他们想相信它,安全公司将始终声称会提供它。

–石油
17年9月18日在19:06

#2 楼

说一个VM或Docker比另一个更安全。

VM提供硬件虚拟化;系统管理程序会仿真硬件,以便来宾内核认为它正在自己的计算机上运行。这种类型的虚拟化更容易彼此隔离。如果您对虚拟化的主要关注是隔离(您实际上并不需要虚拟机进行交互),那么虚拟机的安全性将大大简化。虚拟化,而Docker使用内核名称空间来虚拟化内核和操作系统,以便来宾认为它在自己的操作系统实例上运行。操作系统虚拟化为您如何确保容器之间的互连提供了更大的灵活性。如果您对虚拟化的主要关注需要您互连容器,那么Doc​​ker提供了以虚拟机不可能或过于繁琐的方式定义这些共享规则的功能。错误配置docker比VM更容易,并且docker资源共享的灵活性也为实现和配置错误提供了更多机会。但是,如果您设法正确配置共享权限,并且假设Docker或内核中没有实现错误,那么Doc​​ker提供的共享比硬件虚拟化要细得多,可能会为您提供总体上更好的安全性。 />例如,套接字共享。使用Docker,您可以通过共享套接字文件轻松地在两个容器之间创建一个共享的命名套接字,并且可以在两个容器之间定义安全权限(使用任何现有的安全模块:传统的Unix权限,功能,SELinux,AppArmor,seccomp等)。套接字端点,以便docker / kernel强制应用程序访问套接字端点的方式以及方式。使用虚拟机,您可以通过设置套接字链来通过TCP将流向套接字的数据传递到管道中来使套接字更加繁琐。但是,虚拟机管理程序的可见性非常有限,并且无法控制对套接字端点的访问,因为来宾内核会应用对这些套接字端点的权限。使用容器,您可以通过设置共享安装来共享文件夹,并且由于Docker / kernel强制执行容器使用的文件权限,因此来宾系统无法绕过该限制。对于VM,如果要共享文件夹,则必须让一台计算机运行网络文件服务器,Samba服务器或FTP服务器,并且管理程序对共享的可见性很小,并且无法强制执行共享权限。这里的其他活动部件(文件服务器)也可能有其自身的漏洞和配置错误问题。


评论


很好的平衡答案。我要补充的一件事是,标准容器化的一个主要优点是您只运行一件事。您无需担心ssh是否正在运行以及它是否配置正确。

– JimmyJames
17年9月18日在17:32

Docker不会模拟或虚拟化内核。容器由内核本身实现。 Docker是用于配置和管理它们的工具。

–AndréParamés
17-09-21在16:48



@AndréParamés:不错,我对答案进行了编辑,以更精确地说明实际的容器化本身是如何在内核中完成的。你觉得足够好吗?

– Lie Ryan
17/09/22在3:28

众所周知,VM可以提供更好的隔离性,并具有较小的攻击面。声称虚拟机通常更安全并不是过分简化。

– Federico
18年4月5日在13:08

#3 楼

正如您正确地说的那样,Docker使用“操作系统级虚拟化”。您可以将其视为chroot的一种形式(如果您是* nix爱好者)。

通过利用操作系统中内置的功能,Docker充当了容器的主管。该软件对操作系统的看法由Docker决定。

所有容器都使用相同的内核。因此,例如,如果我能够在一个容器中引起内核恐慌(请考虑“蓝屏死机”),那么所有其他容器都将受到影响。基于解决方案。一切都有效地位于同一共享空间中。想象一下,将野生捕食者放在其天然食物来源旁边。如果您没有在捕食者周围放置足够坚固的外壳,或者每次离开它时都忘记关闭门,那么您可能会想像会发生什么。

虽然肯定是轻巧的解决方案,但我当然,不会在受信任的代码旁边运行任何未知的代码。

恶意代码必须确定一种将特权提升到root / Administrator级别的方法,以便以任何有意义的方式逃避容器

在虚拟机中,系统管理程序将受到攻击,而不是内核。由于“容器”之间存在更高级别的隔离,因此这可能被证明更安全,但是会带来更高的管理开销。

据我了解,没有什么能使Docker比“裸机”或硬件更安全。基于解决方案。我倾向于说Docker不太安全。就每件软件1个容器而言,这可以证明是不同的故事。它使用与Docker类似的样式使用OS级虚拟化,但具有经过修改的内核。

评论


泊坞窗容器也可以访问主机,只是容器配置错误会给您的环境带来很大麻烦。

– dlcardozo
17年9月18日在0:56

我是Linux爱好者,并且将chroot视为提供外观隔离的东西,但在古老的Unix知识中却深陷其中,并拥有许多晦涩的陷阱,以至于根本无法信任它。 Docker真的那么糟糕吗?

– gn
17年9月18日在8:10

docker基于lxc容器,这是对旧unix chroot的现代改造。因此取决于您。

– LvB
17年9月18日在8:12

@BaileyS不,chroot只是一个基本的比较,Docker实际上比简单的chroot(例如,它没有资源限制)要复杂得多。请参阅:LXC了解所使用的实际技术

–乔什
17年9月18日在13:23

@Bailey S chroot是查看Docker的一种非常简化的方法。 Docker使用的实际功能包括cgroups,名称空间和OverlayFS。最新版本将libcontainer与libvirt和LXC结合使用。

– dark_st3alth
17年9月18日在16:38

#4 楼

Docker容器本来并不是“更安全”的,但是从安全的角度来看,在集群中快速启动和销毁副本的能力非常有用。忘记了有时可以用来保护Web服务器/应用程序安全的最佳工具是能够在已安装的代码遭到破坏后快速重新部署干净的代码。

世界上没有100%安全可靠的工具。尤其是在公开的Web应用程序世界中。但是,如果人们真正了解自己的价值并参与其中,那么Doc​​ker会提供更好的做法。


定期对资产和数据库进行备份。
在代码存储库中管理代码。
使用允许在几次击键中重新部署代码的部署过程。
并使用系统配置工具来确保系统/服务器可以快速启动
如果可能的话,可以将代码部署在某种负载平衡的群集中,这样,如果一个正在运行的“事物”代码遭到破坏,则可以在不完全关闭应用程序的情况下将其杀死。
Docker适用于最后一点。 VM也是如此,但是Docker更是如此,因为一旦您决定使用Docker,就必然会使用一种工具,这种工具的心态/心态是:“我不会永远坚持下去。我需要重新创建。”

在受感染的Docker容器的情况下,您可以将其脱机(就外部世界而言),以进行取证,以了解发生的情况并查看如何安全地将代码重新部署到Docker容器内其他现有和新的代码库安装。

VM可能能够以这种方式使用,但是根据我的实践和经验,只有开发人员才真正想到VM。大多数系统管理员以及他们所属的团队将VM视为更轻松地从裸机服务器中挤出更多用途和实用程序的一种方式,而不是将它们视为可以一时兴起的快速使用的一次性计算机。 />
使用Docker,您真的必须尽一切努力使Docker容器成为不可使用的整体。 Docker是应用程序开发人员的工具,专为虚拟化变得快速,廉价和容易的时代而打造。而且,当部署在某种负载平衡的群集中时,您可以获得很少甚至没有停机的稳定性。

评论


这是一个明智的现实答案。任何曾经受到危害的人都知道,“啊哈,我知道如何自动检测到我们被黑了”与“啊哈,我知道,设计了一种可阻止这种特定攻击的变通办法,因此我们可以在分析根本原因以发现漏洞的同时运行该服务。”

– Kubanczyk
17 Sep 24 '21:17



我要补充一点,因为Docker容器是轻量级的,所以与VM相比,它们在实践中也更有可能被使用。而且,当然,它们通常在VM上用作附加层(例如,如果您在AWS上运行Docker容器)。

–阿拉斯泰
17年9月25日9:00

??是的,这真是一种怪异的查看方式。是的,老板,我们所有的数据都已经泄漏/删除/删除了,但是嘿,我可以用干净的代码启动一个新的Docker。

–圣多尔·马顿(Sandor Marton)
17-09-27在8:40



@SandorMarton Security不仅可以防止数据泄漏。它还涉及防止入侵,限制破坏并弄清楚如何恢复,同时保持系统正常运行。如果数据丢失,通常是由于不良的应用程序体系结构和修补失败所致。在这种情况下,Docker,VM或裸机无法保存您的资产。

–Giacomo1968
17年9月27日在13:42

@SandorMarton修改了我的答案以解决您的问题。但是最终,没有什么是100%安全的。期。这是关于限制所有级别的损坏。

–Giacomo1968
17年9月29日在14:42

#5 楼

如果我们只是比较空白VM和空白Docker容器,我同意ThoriumBR的回答。但是,应该注意的是,例如在Red Hat的Atomic Host中正确配置系统可以缓解许多因素,甚至消除一些因素。

此外,由于Docker启动,您可以一方面依靠他的回答中提到了多种类型的漏洞,所有这些漏洞都可以通过SELinux等其他层来缓解。我们还开始看到基于虚拟机管理程序的OCI兼容运行时,如果您确实很偏执并且愿意提高性能,则可以使用它代替runc。

我还要指出,软件中的绝大多数漏洞都不在VM具有安全优势的内核/驱动程序空间中,而是在Docker容器具有优势的应用程序层中,因为它们使创建单进程攻击面更加容易。您可以使用单个静态链接的可执行文件构建可用的Docker容器,该可执行文件以非root用户身份运行,并且资源和功能有限。您不能使虚拟机具有如此小的攻击面。

最重要的是,您必须查看整个安全情况。 Docker容器可能非常安全,但是您必须查看整个软件供应链,并确保正确配置Docker和主机。虚拟机有自己的优点和缺点。您不能只是比较两个“开箱即用”并做出决定。您需要适当的流程来强化任一解决方案。

#6 楼

问题太广泛了,无法用简单的“是”或“否”来回答。

Docker容器有非常清晰和开放的攻击面:


如果攻击者是可以启动容器的人员(即可以访问Docker API),那么他无需采取任何进一步措施即可立即对主机具有完全访问权限。这已经有很多年了,已经被证明,并且没有任何人在争论(Google或SE会立即为您提供简单的命令行,甚至不需要特定的容器即可工作)。
如果攻击者设法获得了root容器内,那么您有麻烦了。实际上,他可以执行任意的内核调用并尝试影响主机内核。不幸的是,许多docker映像似乎以root的形式运行它们的内容,并跳过Dockerfile中的root-这不是Docker问题,而是用户问题。 Docker映像上的安全性更高(可能是...):


如果您虔诚地使映像尽可能小,并且每个关注的映像只有一个。 (即,没有USER而不是--privileged)。
并且网络连接越紧密。 >

安装的底座越小越好。
许多问题都安装在同一VM中。
网络连接越紧密。如果,例如,HTTP服务器被闯入,并且它正在最小容器内运行(我的意思是“最小”),即root,除了最低限度外什么都没有,包括无出站网络,无读写卷等等),则攻击者能够执行任何操作的机率要低于运行其他服务的VM。

显然,这种情况假设虚拟机实际上比容器胖。如果使VM与容器相同,那么这是有争议的。但随后,将设计出一个设计良好的Docker方案。而且通常的VM安装程序至少在一段时间内可能会迁移到越来越多的正在安装的东西。

评论


由于用户名称空间的原因,第二点不再总是正确的。您可以将容器内的root用户映射到外部的普通用户。

–AndréParamés
17/09/21在16:57



#7 楼

已经有了一些不错的答案,但是要完整说明docker和VM之间的区别,我将添加一张图片:



来源

从这个角度来看,更容易理解为什么VM比Docker容器更安全。

#8 楼

docker的主要卖点不是要更安全,而是要更容易。其中包括:


有用的默认值,包括一些安全选项。
无法自行配置LXC,cgroup等。一行。
可复制的VM。不再有“在我的机器上工作”的参数。

Docker与其使用的技术一样安全,这些技术主要是LXC(Linux名称空间),selinux和apparmor。

docker的常用用法通常非常不安全。人们正在使用一行来下载某人制作的图像,他们甚至在运行其操作系统容器之前都从未读过其名称。即使您自己从自己的基本映像(例如,可以使用debootstrap以与构建chroot的相同方式来生成映像)和Dockerfile来构建映像,该Dockerfile通常也包含curl $URL|bash反模式以在其中安装软件容器。

另一件事是,“ docker方法”不是升级映像,而是重建映像。这意味着停止(人们通常会假设您具有使用新映像运行的故障转移),重建并重新开始。

这来自创建快照的方式,通常apt-get dist-upgrade引入了从docker的角度来看,从语义上讲是噪音,在这些步骤之间,历史记录应类似于“ baseimage”,“添加的apache”,“添加的php”,“已安装的roundcube”,而无需“每日apt-get upgrade”。 br />如果您要在LAN中维护自己的映像存储库,则docker可能会非常有用,因为您可以快速重新部署更新的映像。

快照功能是另外一回事当您可以快速回滚或分叉图像以在测试环境中尝试新的东西,然后将容器重置为安全状态时,这是一个很好的安全改进。

最重要的是,对于开发人员来说,docker是一个非常有用的工具,他们想要测试可重现的代码部署并且无需更改已安装的操作系统,但是有更好的生产解决方案。因此,您可以在生产环境中安全地运行docker,但它不会比没有docker的LXC设置更好。很快就会受到限制,尤其是当它们也以Windows为目标时。选择另一个后端具有与LXC,KVM和VirtualBox相同的安全隐患。其他几点可能保持不变。

#9 楼

首先,我想指出的是,越难重复使用/共享相同资源,就越容易保证其安全性。

说,Docker尝试在沙盒(容器)上运行每个进程,这是为什么可以认为Docker更安全的唯一原因。从理论上讲,通过服务器运行的多个进程,您将可以访问自己的进程,并将共享文件夹或套接字公开给其他进程。即使在同一台“机器”上,也无法访问配置文件,凭据,秘密其他调试和维护端口/套接字。处理。在Virtual Machines和Baremetal上,您可以对一组进程和应用程序进行沙盒化,并在它们之间进行相应的设置权限。