浅谈 Docker 隔离性和安全性

介绍

相信很多开发者都默认Docker这样的容器是一种沙盒(sandbox)应用,也就是说他们可以用root权限在Docker中运行随便什么应用,而Docker有安全机制能保护宿主系统。比如,有些人觉得Docker容器里面的进程跟虚拟机里面的进程一样安全;还有的人随便找个源就下载没有验证过的Docker镜像,看都不看内容就在宿主机器上尝试、学习和研究;还有一些提供PaaS服务的公司竟然允许用户向多租户系统中提交自己定制的Docker镜像。请注意,上述行为均是不安全的。

 本文将介绍Docker的隔离性和安全性,以及为什么它在隔离和安全性上不如传统的虚拟机。

更多信息

何谓安全性?

单单就Docker来说,安全性可以概括为两点:

  1. 不会对主机造成影响
  2. 不会对其他容器造成影响

所以安全性问题90%以上可以归结为隔离性问题。而Docker的安全问题本质上就是容器技术的安全性问题,这包括共用内核问题以及Namespace还不够完善的限制:

  • /proc、/sys等未完全隔离
  • Top, free, iostat等命令展示的信息未隔离
  • Root用户未隔离
  • /dev设备未隔离
  • 内核模块未隔离
  • SELinux、time、syslog等所有现有Namespace之外的信息都未隔离

当然,镜像本身不安全也会导致安全性问题。

真的不如虚拟机安全?

其实传统虚拟机系统也绝非100%安全,只需攻破Hypervisor便足以令整个虚拟机毁于一旦,问题是有谁能随随便便就攻破吗?如上所述,Docker的隔离性主要运用Namespace 技术。传统上Linux中的PID是唯一且独立的,在正常情况下,用户不会看见重复的PID。然而在Docker采用了Namespace,从而令相同的PID可于不同的Namespace中独立存在。举个例子,A Container 之中PID=1是A程序,而B Container之中的PID=1同样可以是A程序。虽然Docker可透过Namespace的方式分隔出看似是独立的空间,然而Linux内核(Kernel)却不能Namespace,所以即使有多个Container,所有的system call其实都是通过主机的内核处理,这便为Docker留下了不可否认的安全问题。

传统的虚拟机同样地很多操作都需要通过内核处理,但这只是虚拟机的内核,并非宿主主机内核。因此万一出现问题时,最多只影响到虚拟系统本身。当然你可以说黑客可以先Hack虚拟机的内核,然后再找寻Hypervisor的漏洞同时不能被发现,之后再攻破SELinux,然后向主机内核发动攻击。文字表达起来都嫌繁复,更何况实际执行?所以Docker是很好用,但在迁移业务系统至其上时,请务必注意安全性!

如何解决?

在接纳了“容器并不是全封闭”这种思想以后,开源社区尤其是红帽公司,连同Docker一起改进Docker的安全性,改进项主要包括保护宿主不受容器内部运行进程的入侵、防止容器之间相互破坏。开源社区在解决Docker安全性问题上的努力包括:

  • Audit namespace

    • 作用:隔离审计功能
    • 未合入原因:意义不大,而且会增加audit的复杂度,难以维护。
  • Syslognamespace
    •  作用:隔离系统日志
    • 未合入原因:很难完美的区分哪些log应该属于某个container。
  • Device namespace
    • 作用:隔离设备(支持设备同时在多个容器中使用)
    • 未合入原因:几乎要修改所有驱动,改动太大。
  • Time namespace
    • 作用:使每个容器有自己的系统时间
    • 未合入原因:一些设计细节上未达成一致,而且感觉应用场景不多。
  • Task count cgroup
    • 作用:限制cgroup中的进程数,可以解决fork bomb的问题
    • 未合入原因:不太必要,增加了复杂性,kmemlimit可以实现类似的效果。(最近可能会被合入)
  • 隔离/proc/meminfo的信息显示
    • 作用:在容器中看到属于自己的meminfo信息
    • 未合入原因:cgroupfs已经导出了所有信息,/proc展现的工作可以由用户态实现,比如fuse。

不过,从08年cgroup/ns基本成型后,至今还没有新的namespace加入内核,cgroup在子系统上做了简单的补充,多数工作都是对原有subsystem的完善。内核社区对容器技术要求的隔离性,本的原则是够用就好,不能把内核搞的太复杂。

一些企业也做了很多工作,比如一些项目团队采用了层叠式的安全机制,这些可选的安全机制具体如下:

1、文件系统级防护

  • 文件系统只读:有些Linux系统的内核文件系统必须要mount到容器环境里,否则容器里的进程就会罢工。这给恶意进程非常大的便利,但是大部分运行在容器里的App其实并不需要向文件系统写入数据。基于这种情况,开发者可以在mount时使用只读模式。比如下面几个: /sys 、/proc/sys 、/proc/sysrq-trigger 、 /proc/irq、/proc/bus
  • 写入时复制(Copy-On-Write):Docker采用的就是这样的文件系统。所有运行的容器可以先共享一个基本文件系统镜像,一旦需要向文件系统写数据,就引导它写到与该容器相关的另一个特定文件系统中。这样的机制避免了一个容器看到另一个容器的数据,而且容器也无法通过修改文件系统的内容来影响其他容器。

2、Capability机制

Linux对Capability机制阐述的还是比较清楚的,即为了进行权限检查,传统的UNIX对进程实现了两种不同的归类,高权限进程(用户ID为0,超级用户或者root),以及低权限进程(UID不为0的)。高权限进程完全避免了各种权限检查,而低权限进程则要接受所有权限检查,会被检查如UID、GID和组清单是否有效。从2.2内核开始,Linux把原来和超级用户相关的高级权限划分成为不同的单元,称为Capability,这样就可以独立对特定的Capability进行使能或禁止。通常来讲,不合理的禁止Capability,会导致应用崩溃,因此对于Docker这样的容器,既要安全,又要保证其可用性。开发者需要从功能性、可用性以及安全性多方面综合权衡Capability的设置。目前Docker安装时默认开启的Capability列表一直是开发社区争议的焦点,作为普通开发者,可以通过命令行来改变其默认设置。

3、NameSpace机制

Docker提供的一些命名空间也从某种程度上提供了安全保护,比如PID命名空间,它会将全部未运行在开发者当前容器里的进程隐藏。如果恶意程序看都看不见这些进程,攻击起来应该也会麻烦一些。另外,如果开发者终止pid是1的进程命名空间,容器里面所有的进程就会被全部自动终止,这意味着管理员可以非常容易地关掉容器。此外还有网络命名空间,方便管理员通过路由规则和iptable来构建容器的网络环境,这样容器内部的进程就只能使用管理员许可的特定网络。如只能访问公网的、只能访问本地的和两个容器之间用于过滤内容的容器。

4、Cgroups机制

主要是针对拒绝服务攻击。恶意进程会通过占有系统全部资源来进行系统攻击。Cgroups机制可以避免这种情况的发生,如CPU的cgroups可以在一个Docker容器试图破坏CPU的时候登录并制止恶意进程。管理员需要设计更多的cgroups,用于控制那些打开过多文件或者过多子进程等资源的进程。

5、SELinux

SELinux是一个标签系统,进程有标签,每个文件、目录、系统对象都有标签。SELinux通过撰写标签进程和标签对象之间访问规则来进行安全保护。它实现的是一种叫做MAC(Mandatory Access Control)的系统,即对象的所有者不能控制别人访问对象。

安全建议

最简单的就是不要把Docker容器当成可以完全替代虚拟机的东西。跑在Docker容器中的应用在很长一段时间内都将会是选择性的,通常只跑测试系统或可信业务。

门槛再高一点,我们对系统做减法,通过各种限制来达到安全性。这也是最主流的、有效的安全加固方法,比如上一章节介绍的几种安全机制。同时一定要保证内核的安全和稳定。外部工具的监控、容错等系统也必不可少。

总之通过适配、加固的Docker容器方案,在安全性上完全可以达到商用标准。就是可能对实施人员的技术要求和门槛较高。

参考

Docker在线文档:Docker Security

OpenSource.com:Bringing new security features to Docker

InfoQ:从社区和内核看Docker隔离性和安全性发展

原文发布时间为:2015-05-29

时间: 2024-08-02 07:01:28

浅谈 Docker 隔离性和安全性的相关文章

Docker五大优势:持续集成、版本控制、可移植性、隔离性和安全性

本文讲的是Docker五大优势:持续集成.版本控制.可移植性.隔离性和安全性,[编者的话] 随着Docker技术的不断成熟,越来越多的企业开始考虑使用Docker.Docker有很多的优势,本文主要讲述了Docker的五个最重要优势,即持续集成.版本控制.可移植性.隔离性和安全性. 对于Docker,应该不需要进行详细的介绍了.它是最火热的开源项目之一,通过在容器中增加一个抽象层(a layer of abstraction),就可以将应用程序部署到容器中.在看似稳定而成熟的场景下,使用Dock

DockOne微信分享(七十):浅谈Docker安全合规建设

本文讲的是DockOne微信分享(七十):浅谈Docker安全合规建设[编者的话]通过阅读网上帖子及浏览相关信息,大家可能会产生一种错觉:Docker安全性不足,对Docker导入生产环境持保守态度.不过实际情况是,虽然我们需要对容器的安全性高度关注,但只要使用得当,完全可以成为一种不低于使用虚拟机或者裸机的安全.高效生产系统. 今天和大家聊聊Docker的安全合规建设. 安全,这里我们指的是信息安全,包括数据安全和网络安全,主要是数据在处理.传输.存储等过程中的安全,它包括了信息本身的安全和防

浅谈Docker与容器

Docker介绍 1. Docker 主要解决什么问题 Docker 对外宣称的是Build.Ship 和Run,Docker 要解决的核心问题就是快速地干这三件事情.它通过将运行环境和应用程序打包到一起,来解决部署的环境依赖问题,真正做到跨平台的分发和使用.而这一点和DevOps不谋而合,通过Docker可以大大提升开发.测试和运维的效率.在这个移动互联网的时代,如果一个工具能够节省人力,提升效率,必定会流行起来. 2. Docker 的历史 之前提到一家公司叫DotCloud,这家公司是一家

浅谈InnoDB隔离模式的使用对MySQL性能造成的影响_Mysql

在这篇文章里我将讨论一个相关的主题 – InnoDB 事务隔离模式,还有它们与MVCC(多版本并发控制)的关系,以及它们是如何影响MySQL性能的. MySQL手册提供了一个关于MySQL支持的事务隔离模式的恰当描述 – 在这里我并不会再重复,而是聚焦到对性能的影响上. SERIALIZABLE – 这是最强的隔离模式,本质上打败了在锁管理(设置锁是很昂贵的)的条件下,多版本控制对所有选择进行锁定造成大量的开销,还有你得到的并发.这个模式仅在MySQL应用中非常特殊的情况下使用. REPEATA

浅谈php安全性需要注意的几点事项_php技巧

在放假之初,我抽时间看了<白帽子讲web安全>,吴翰清基本上把web安全中所有能够遇到的问题.解决思路归纳总结得很清晰,也是我这一次整体代码安全性的基石. 我希望能分如下几个方面来分享自己的经验 把握整站的结构,避免泄露站点敏感目录 在写代码之初,我也是像很多老源码一样,在根目录下放上index.php.register.php.login.php,用户点击注册页面,就跳转到http://localhost/register.php.并没有太多的结构的思想,像这样的代码结构,最大的问题倒不是安

浅谈MySQL中的事务隔离级别(r11笔记第86天)

   之前写了一篇浅谈事务(一),算是对事务的一个基本认识,今天来简单总结一下事务的隔离级别,虽然是老掉牙的知识点,重温一下还是值得的.    在MySQL中基本有这两种事务隔离级别的设置,默认的RR(Repeatable-Read)和实际中常见的RC(Read-Committed).两者区别是什么,怎么正确理解,用几个SQL语句就能说明白,就用简单的实验来说明白.    我们开始吧.        首先创建一个测试表test,插入一些数据. create table test( id int

浅谈web网站架构演变过程

原文:浅谈web网站架构演变过程 前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变.   该系统具备的功能:   用户模块:用户注册和管理 商品模块:商品展示和管理 交易模块:创建交易和管理    阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架如maven+spring+struct+hibernate.

游戏云间之浅谈游戏运维

浅谈游戏运维--游戏云间系列三 一款游戏产品上线,仅仅从技术角度来讲,分为软件层次的游戏代码研发,及硬件层次的代码部署上线.劈开代码研发方面不讲,游戏的部署上线,成为我们一个很头疼的问题.为什么头疼?从一些报告显示,大部分的游戏生命周期仅有3个月.按照正规的上线流程,从买服务器,装环境,进IDC机房这么下来,刚把游戏上线,可是游戏却不给力.这样折腾下来,浪费了多少我们的青春?浪费了多少我们的血汗钱? 一般游戏的部署有以下几种方式: 1.托管IDC机房部署. 2.代理商部署. 3.租用vps环境部

浅谈关于JavaScript API设计的一些建议和准则

  这篇文章主要介绍了浅谈关于JavaScript API设计的一些建议和准则,文中列举了许多知名的JS API进行辅助说明,极力推荐!需要的朋友可以参考下 设计是一个很普遍的概念,一般是可以理解为为即将做的某件事先形成一个计划或框架. (牛津英语词典)中,设计是一种将艺术,体系,硬件或者更多的东西编织到一块的主线.软件设计,特别是作为软件设计的次类的API设计,也是一样的.但是API设计常常很少关注软件发展,因为为其他程序员写代码的重要性要次于应用UI设计和最终用户体验. 但是API设计,作为