玩转容器安全 - 容器安全概述
容器安全概述
根据我自己的理解,将容器安全划分成了6个方向,各个方面还存在二级分支方向,本文就这6个方向及其二级分支展开我对容器安全的理解。话不多说,开篇一幅图,后面全靠编。
承载容器或容器集群的宿主机的安全性
首先就是容器宿主机的安全,在一个企业内部,如果划分了基础运维团队与容器团队(CaaS, Container as a Service 容器即服务),那么容器宿主机的安全性由基础运维团队负责,通常与传统基础设施安全保持一致。这块就是一些老生常谈的话题,如:
主机身份鉴别与访问控制:主要是操作系统的特权账号与普通账号管理、账号权限管理、密码策略、登录策略等;
补丁更新:补丁定期更新策略、高危漏洞补丁及时更新策略等。这一块,基础运维团队除了应该关注会对宿主机自身造成中高风险的漏洞,还应关注与Docker相关的漏洞,如:利用DirtyCow漏洞实现Docker逃逸;
安全防护能力:主要是部署入侵检测与防护产品、防病毒产品,定期更新安全产品的软件版本与防护策略等;
运行容器的用户权限:这里需要理解一下Docker容器中的uid与gid相关概念,就能发现如果使用特权用户启动容器会出现哪些风险,但是根据目前我片面的了解来看,大部分都没有配置特定用户权限来启动容器;
审计和配置容器守护程序目录或文件:/var/lib/docker, /etc/docker, docker.service, docker.socket, /etc/default/docker/, /etc/docker/daemon.json, /usr/bin/docker-containerd, /usr/bin/docker-runc需要对这些文件执行审计,并配置合理的权限,关于审计内容与权限设置的要求,请参见附录Docker容器最佳安全实践白皮书V1.0。
容器软件自身的安全性
其次就是容器软件Docker自身的安全性,这里我引用了以下链接的部分内容:
技术干货 | Docker 容器逃逸案例汇集
https://www.cnblogs.com/xiaozi/p/13423853.html
docker remote api未授权访问漏洞;
docker.sock挂载到容器内部:此场景容易出现在Jenkins CI/CD流程中;
docker高危启动参数:
--privileged:特权模式,此场景也容易出现在Jenkins CI/CD流程中;
-v:挂载敏感目录;
--cap-add=SYS_ADMIN:允许执行mount操作;
--net=host:绕过Network Namespace;
--pid=host:绕过PID Namespace;
--ipc=host:绕过IPC Namespace。
Shocker攻击
CVE-2014-5277:Docker和docker-py代码注入漏洞;
CVE-2014-6408:Docker权限许可和访问控制漏洞;
CVE-2014-9357:Docker权限许可和访问控制漏洞;
CVE-2014-9358:Docker目录遍历漏洞;
CVE-2015-3627:Docker Libcontainer和Engine权限许可和访问控制漏洞;
CVE-2015-3630:Docker Libcontainer与Engine安全绕过漏洞;
CVE-2019-14271:docker cp命令导致容器逃逸;
CVE-2019-5736:docker runc容器逃逸。
更多docker漏洞信息:https://www.cvedetails.com/vulnerability-list/vendor_id-13534/product_id-28125/Docker-Docker.html
对于容器软件自身的安全性来说,定期更新docker版本或在docker出现高危漏洞时及时更新版本就能解决此类型问题。但由于docker本身是作为底层资源,版本升级可能会要求重启服务这就会影响业务的正常运行。所以我们在解决版本升级这类型的问题时,按以下步骤来解决:
补偿性的控制措施:通过第一节内容保护宿主机安全,加强容器的访问控制,加固运行在容器中的应用程序等实现降级处理;
临时解决方案:通过一些安全产品或官方提供的临时解决方案来保护容器安全,很多时候临时解决方案可以一定程度上规避风险,但不应该将临时解决方案作为最终解决方案;
分阶段进行版本更新:容器在企业内部的使用大都应用了负载均衡技术,我们可以划分阶段来进行版本更新动作,但是如果容器环境管理比较混乱,此方案可行性较低;
新环境中解决此类型的问题:对于后期构建的容器环境必须使用包含补丁的版本。
整体来说,docker版本升级是高危操作,但依旧需要根据漏洞风险和企业实际情况来制定更新计划,如2018年的docker runc容器逃逸漏洞修复方案:https://developer.aliyun.com/article/690053。
容器的安全基线与合规性要求
主流的容器安全基线有两个大的板块:Docker与Kubernetes,CIS分别对其作出了要求,这里我们简单对比一下CIS_Docker_1.13.0_Benchmark_v1.0.0与CIS_Kubernetes_Benchmark_v1.5.1:
CIS_Docker_1.13.0_Benchmark_v1.0.0 | CIS_Kubernetes_Benchmark_v1.5.1 |
Host Configuration | Control Plane Components |
Docker daemon configuration | etcd |
Docker daemon configuration files | Control Plane Configuration |
Container Images and Build File | Worker Nodes |
Container Runtime | Policies |
Docker Security Operations |
对比两者我们可以发现,Docker基线章节也就是本文的第一章的内容,而Kubernetes基线更多关心的是集群管理的问题,同时Kubernetes安全是基于在Docker安全的拔高要求,在本章的第6节我会简单列举Docker集群的安全性,后期我会通过一篇专门的文章来梳理一下Kubernetes集群的安全性。
PS:在上述提到的附录Docker容器最佳安全实践白皮书V1.0其实就是翻译了Docker Benchmark内容,推荐大家去看CIS的官方文档,中文翻译有一些描述上的偏差。我将两个文档共享在:https://share.weiyun.com/A3G1wWMo
容器镜像的安全性
接下来就是容器安全中尤为重要的一个版块,我将其分为:
基础镜像的安全性
镜像是一层一层构建而来,很多操作系统、应用程序的基础镜像构建都是对应的官方与Docker Hub构建的。我们在使用这部分镜像需要注意的是基础镜像包含安全漏洞,如CentOS 5.11与CentOS 6.6的基础镜像中就包含CVE-2014-6277漏洞;其次就是我们使用存在供应链攻击的基础镜像或非官方基础镜像(Bad Image, 恶意镜像),这些镜像中可能包含恶意程序、后门等。
对于基础镜像的安全性,首先是尽可能不要使用非官方的基础镜像,其次就是需要对使用的基础镜像执行漏洞扫描并修复扫描发现的漏洞。
镜像构建的安全性
镜像构建的方式有两种,第一种是拉取基础镜像,然后通过基础镜像创建容器,在容器中执行相应的操作,最后将容器打包成镜像并上传到镜像仓库以备后期;第二种是通过Dockerfile来构建镜像。那么这两种构建过程中可能的安全风险如下:
最小权限原则:软件安装、端口暴露;
Dockerfile文件包含敏感信息。
镜像仓库的安全性
在企业内部,随着容器化的不断发展,团队会构建私有镜像仓库来存储基础镜像、业务镜像等。其安全性尤为重要,在私有镜像仓库这块,通过我的实践主要是以下几个方面的问题:
镜像仓库是否使用HTTPS:这一点上如果私有仓库不会通过互联网,只通过局域网对镜像仓库即可进行操作则可不予理会;
镜像仓库对镜像的校验能力:目前开源的私有镜像仓库都具备这个能力,但是部分需要手工配置;
镜像仓库的身份鉴别与访问控制:这一点是私有镜像仓库最重要的一点,首先是访问私有镜像仓库需要身份鉴别与认证;其次就是镜像仓库内不同业务的镜像需要具有访问控制的能力;
镜像仓库的审计能力:镜像仓库应该具备对镜像操作的审计能力;
容器运行时的监控、入侵检测与安全防护
对于容器资源监控与使用方面,目前已有一些开源或成熟的商业系统可以支持,如Grafana、Prometheus。但是对于容器的安全监控商业产品我了解相对较少,所以我在本文中我只会列出一些容器运行状态下的安全问题:
Docker Security Capability:
AppArmor: AppArmor(应用程序防护)是一种Linux安全模块,可保护操作系统及其应用程序免受安全威胁;
SELinux: SELinux是一个应用程序安全系统,它提供了一个访问控制系统,大大增强了自由访问控制模型;
Seccomp: Seccomp是一种Linux内核功能,可用于限制容器中可用的操作;
不使用--privileged参数启动容器;
端口开放必须遵循最小权限原则,不暴露未使用的端口;
不在容器中启用SSH服务;不共享主机的网络命名空间(Namespace),也就是不要使用--net=host参数启动容器;
设置故障容器自动重启策略,也就是使用--restart参数;
容器根文件系统设置为只读;
对容器的出口流量进行安全分析,接入NIDS进行分析;
等等
容器集群的安全性
对于容器集群Kubernete安全较重要的如下:
控制对Kubernetes API的访问:TLS APII、API认证与授权;
控制对Kubernetes Kubelet的访问;
在运行时控制工作负载或用户的功能:
限制集群中的资源使用;
控制容器的运行权限;
防止容器加载不必要的内核模块;
限制网络访问;
限制云元数据API访问;
控制Pod可以访问哪些节点。
保护集群组件:
限制访问etcd;
启用审计日志
限制访问alpha或beta功能;
定期轮换基础架构的凭据;
集成第三方组件之前必须执行审计;
加密静止的密钥;
接收安全更新警报并报告漏洞。
如同上面所说,集群安全已经算是容器安全的另一个主题,所以本文对集群的安全不过多描述(主要是我还没有吃透)。
容器的安全工具
容器在前几年发展迅速,安全问题也得到了相应的重视,业内出现了很多针对容器安全的工具。当然工具不是本篇文章的重点,后续我会更新关于容器安全工具的安装、使用与对比。这部分主要来源于:https://sysdig.com/blog/33-kubernetes-security-tools/