查看原文
其他

浅析云技术安全攻防实践与防护之容器安全

中国光大银行 中国光大银行科技创新实验室 2024-01-09

随着容器技术的盛行,越来越多的工程师们愿意使用Docker容器技术作为微服务的运行环境。但Docker新技术的出现必然会带来新的安全挑战,本文将从Docker原理出发,分析容器技术可能面临的风险,提出容器技术的安全防护措施及如何构建容器全生命周期的安全防护。



Docker原理

1.1

 Docker组件 

Docker是一个C/S架构程序,当Docker服务启动后,系统上有dockerd、docker-containerd等进程,下面以docker1.11版本介绍4个主要组件和3个关键要素。


主要组件:

(1)dockerd守护进程,负责与容器客户端交互,并管理Docker镜像、容器。

(2)docker-containerd容器管理进程,是为了兼容OCI标准,具有容器运行时及其管理功能。

(3)containerd-shim是容器的运行时载体,介于containerd与runC之间,负责管理单个运行的容器。

(4)docker-runc是containerd-shim进程的子进程,负责启动容器,即根据配置找到容器的rootfs并创建子进程bash,之后进程bash将由runC的父进程containerd-shim接管。


主要要素:

(1)镜像:一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的配置参数。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

(2)容器:镜像创建的运行实例,Docker利用容器来运行应用。每个容器都是相互隔离的、保证安全的平台。我们可以把容器看做是一个轻量级的Linux运行环境。

(3)镜像仓库:集中存放镜像文件的地方。用户创建完镜像后,可以将其上传到公共仓库或者私有仓库,使用镜像时,只要从仓库上下载即可。


1.2

 Docker底层技术 

Docker可以实现对资源的限制及进程间的隔离,并让镜像可以无需多余配置在其它环境中运行,主要得益于Docker三大核心底层技术:Namespaces、Cgroups和Union File System。


 (1)Namespaces(命名空间)实现了容器间资源的隔离,让Linux下的PID、IPC、网络等全局资源,限制在某个特定的Namespace中,使各个Namespace下的资源互不干扰,使得每个Namespace看上去像一个独立的操作系统一样。


(2)Cgroups(资源控制组)实现进程对CPU、内存、磁盘、网络等资源访问的控制,让不同容器在同一宿主机上可以互不干扰,平等使用物理资源。


(3)AUFS(联合文件系统)实现不同文件系统结构的镜像层进行叠加挂载,让镜像文件可以跨平台运行。


图1 各组件间的工作流程


图1为各组件间的工作流程:

(1)客户端向dockerd发送请求构建镜像文件,docker在本地生成本地镜像文件;

(2)客户端dockerd发送请求运行容器,dockerd将请求给containerd,containerd首先做一些初始化工作,然后启动containerd-shim进程配置并反馈相关参数,并启动runC进程,runC进程找到本地镜像文件信息,启动镜像,并将生成的容器进程交给containerd-shim管理;

(3)镜像文件运行没问题,客户端发送请求上传镜像,docker将本地镜像文件上传到镜像仓库。



容器技术面临的风险

Docker工作流程图较为全面地展现了Docker用户在使用容器的过程中涉及的组件及操作,主要包含Docker客户端、Docker服务和镜像仓库三部分,以下从七个方面分析Dokcer容器技术可能面临的风险。


2.1

 Docker镜像存在的风险 

我们从镜像的内容、流转过程分析Docker镜像可能存在的风险。


(1)不安全的三方组件

随着开源软件和开源组件的流行,许多容器开发者直接将这些容器镜像和Dockerfile作为基础镜像,打包进最终业务镜像并上线运行。如果这些镜像含有不安全的三方组件,攻击者可能会利用三方组件漏洞入侵容器,进而给业务带来风险。


(2)恶意镜像的传播

除了风险可控的开源镜像外,那些公共镜像仓库(如Docker Hub、Harbor、阿里云镜像仓库)中可能存在一些恶意镜像。如果把这些镜像作为基础镜像,其风险不言自明。


(3)敏感信息的泄露

容器开发者在开发、调试过程中,为了方便将一些敏感信息(如密钥、密码、证书、IP、端口)直接写在源码或配置文件中。在构建镜像时,这些敏感信息被打包进镜像并上传到公共镜像仓库,将会导致信息泄露风险。


2.2

 Docker活动容器存在的风险 

当镜像以容器的形式运行起来后,即容器,针对容器,我们从容器自身业务和容器资源利用情况,分析活动容器可能存在的风险。


(1)不安全的容器应用

与传统应用类似,运行在容器环境下的业务本身也可能存在安全漏洞(如SQL注入、命令注入、文件上传、反序列化、缓冲区溢出等)。当容器对外提供服务时,攻击者就可能会利用这些漏洞入侵容器。


(2)不受限制的资源共享

在Docker默认情况下,容器可以不受限制地使用宿主机的计算、存储等资源。如果某个容器使用过多资源,就会对宿主机上的其它容器造成影响,也可能会出现拒绝服务攻击。


(3)不安全的配置与挂载

容器配置和目录挂载对活动容器至关重要,如果容器配置不当或目录挂载不当,可能会导致容器的隔离机制被打破,进而影响宿主机的安全。


2.3

 Docker网络存在的风险 

Docker容器启动时,会通过Networkdriver模块完成容器网络环境的配置,如网桥、IP、端口及与宿主机的NAT端口映射、容器防火墙策略等。容器间通过网桥(bridge)交互信息时,可能会被中间人攻击利用,如ARP欺骗、DNS劫持,同时容器与宿主机的NAT端口映射不当,可进一步对宿主机发起攻击。


2.4

 Dokcer守护进程接口存在的风险 

Docker守护进程提供Unix socket和TCP socket两种接口,用于接受请求和返回响应。


默认情况下,Docker守护进程只监听Unix socket,且Docker守护进程默认以宿主机的root权限运行,导致攻击者可以借助Docker守护进程的root权限在宿主机上进行操作。比如:1.为了操作方便,减少用户验证,将普通用户加入docker用户组,一旦攻击者获取普通用户权限,就可以借助Unix socket接口在宿主机上提升为root权限。2.由于用户挂载不当,将Unix socket挂载到容器内部,当攻击者入侵了容器,就可以通过这个接口获取宿主机的root权限。


TCP socket默认下不开启,如果工程师通过配置文件开启了TCP socket接口,且未配置加密和认证项,那么任何访问者都可借助此接口对Docker守护进程发送命令。


2.5

 Docker自身存在的风险 

“软件在重新定义我们的世界。但是,只要是人写的软件,都会有漏洞”,Docker也不例外,CVE官方记录的Docker历史版本共有超过20项漏洞,可见Docker自身存在漏洞也给Dokcer容器技术的使用者带来一定的风险。


2.6

 Docker宿主机内核存在的风险 

通常,容器与宿主机共享内核,如果宿主机内核存在安全漏洞,那么此漏洞在容器内也可利用。借此,攻击者可通过内核漏洞,实现权限提升,并从容器中逃逸,获取宿主机的控制权。



容器技术的安全防护措施

为确保容器安全,不仅需要传统的安全加固,还需要针对容器技术本身的安全加固,如针对镜像、守护进程、活动容器、隔离技术等,及容器全生命周期的安全防护。


3.1

 容器镜像的安全防护 

容器镜像作为容器运行的基础,其安全性在整个容器生命周期中占据重要位置。以下从四个方面提出容器镜像安全防护的建议:


(1)容器镜像构建安全

一是开启Docker内容信任机制(即export DOCKER_CONTENT_TRUST=1);

二是使用Dockerfile方式,透明化构建镜像,排除多余依赖包或软件包;

三是使用COPY代替ADD指令引入外部文件;

四是使用Kubernetes和Docker Swarm的加密功能,管理Dockerfile文件,避免敏感信息泄露;

五是禁用setuid 和 setgid,即在Dockerfile文件后增加“RUN find / -perm /6000 -type f -exec chmod a-s {} \; || true”指令等。


(2)容器镜像仓库安全

在使用公有镜像仓库时:

一是确保公有镜像仓库为官方发布的最新版本镜像仓库,并保持定期更新;

二是下载的镜像不仅要进行应用层面的安全扫描,而且也要进行操作系统层面的扫描,同时优先使用自己Dockerfile构建。


使用私有镜像仓库时:

一是为私有仓库的配置安全证书;

二是配置用户的访问权限;三是启用双向HTTPS或密码验证机制。


(3)容器镜像安全检测

一是针对官方发布的镜像,可使用Docker Security Scanning、Clair和Anchore等工具进行安全扫描,主要检测是否存在已知CVE漏洞;

二是针对非官方镜像,使用商用工具或人工排查可疑端口、环境变量、操作命令或冗余文件等信息。


(4)容器镜像传输安全,镜像在上传和下载时须保证完整性和秘密性

一是使用数字签名,保证上传的镜像在使用时未被篡改;

二是使用HTTPS方式链接镜像仓库,避免使用--insecure-registry选项;


3.2

 活动容器的安全防护 

活动容器的安全主要从运行前安全配置和运行中安全操作方面提出防护建议:


(1)运行前安全配置

一是避免使用--net=host参数运行容器,该参数可以打破容器与宿主机间的网络隔离;

二是避免使用--pid=host参数运行容器,该参数可以打破容器与宿主机间的进程隔离;

三是避免使用--ipc=host参数运行容器,该参数可以打破容器与宿主机间的内存隔离;

四是尽量使用SELinux相关安全策略启动容器,如添加docker daemon --selinux-enabled项。

五是避免使用--volume=/hostPath:/containerPath:shared参数运行容器,该参数可以打破容器与宿主机间的文件系统隔离。

六是限制容器的内核能力(kernel capabilities),如非必要去除容器NET_RAW权限。


(2)运行中安全操作

一是检查运行中的容器是否以root权限运行,可使用如下命令查看docker ps --quiet | xargs --max-args=1 -I{} docker exec {} cat /proc/1/status;

二是检查运行中的容器否是安装了所需的软件,可以使用docker execrpm -qa命令;

三是避免使用sshd服务进入容器,应通过docker exec或docker attach指令进入运行中的容器;

四是避免使用--privileged参数进入容器,此参数将使容器内权限变得与宿主机一样;

五是实现对容器运行情况的可观测,如收集容器运行日志,分析日志数据形成指标,衡量容器是否被入侵,追踪数据处理过程。


3.3

 容器网络的安全防护 

在轻量级虚拟化的容器网络中,容器网络实现了同一宿主机内容器互联、跨宿主机容器互联、容器集群网络等功能,使得容器网络的安全防护更加复杂,以下针对容器网络提出的一些防护措施:

一是避免使用默认网桥docker0运行容器,采用自定义网桥,更好保障相同网络域(network)内的容器相互访问;

二是避免将容器端口映射到宿主机的特权端口上(特权端口号小于1024);

三是仅开启需要的端口,尽量使用-p或--publish参数明确要启用的端口号;

四是只有指定端口的流量可以进入容器,如docker run --detach --publish 10.2.3.4:49153:80 nginx 容器端口80绑定49153且仅接收101.22.13.25主机发送的外部流量信息;

五是配置容器的防火墙策略(即iptables内容),同时实现对容器东西及南北向流量的监控,如Cilium网络安全实现方案。


3.4

 守护进程的安全防护 

容器守护进程在整个容器生命周期内起到了承上启下中枢作用,它接收并响应外部指令,创建其它进程,维护容器安全有序地运行。针对容器守护进程,提出以下防护措施:

一是避免以root用户运行容器,当容器被入侵时,root用户更容易导致容器逃逸;

二是确保守护进程的配置文件被正确设置,如docker.service、docker.socket、/etc/docker文件,设置用户为root、权限为644,证书文件用户为root、权限为444等。

三是避免启用对TCP socket监听模式,守护进程对此模式的访问是无加密且无认证的。


3.5

 宿主机的安全防护 

容器是构建于宿主机之上的轻量级虚拟化技术,其实现离不开宿主机提供的Namespace、Cgroups、Capability、Seccomp等技术。以下从两个方面三个方面提出宿主机的防护措施。

一是评估新版系统内核对容器无影响的情况下,及时升级内核。

二是为容器与宿主机间提供额外的隔离层,即安全容器,避免容器直接访问宿主机,代表性的实现技术有gVisor和Kata Containers。

三是对宿主机进程进行监视,包括但不限于进程权限升级监视、可疑进程监视;


3.6

 容器全生命周期的安全防护 

容器技术的出现让开发、测试、运维一体化(DevOps)开发模式得以快速发展,如何结合传统5A(身份认证、授权、访问控制、审计、资产保护)安全防护要求将容器的安全防护贯彻整个证明周期,以下结合DevSecOps理念提出容器全生命周期的安全防护。


开发过程:此过程中,除针对业务本身的安全需求、安全设计、安全开发的常规安全管控措施外,针对容器的构建安全,排查Dockerfile文件是否包含敏感信息(如密码密钥、IP、令牌等),分析镜像的软件组成是否包含恶意文件、病毒、风险组件及所引用依赖库的安全检测,避免镜像带病入库。


交付过程:此过程中,除传统的安全配置管理、安全构建管理、安全测试管理及安全部署与发布管理,针对容器需考虑到,镜像入库前是否安全,镜像仓库是否安全,镜像来源是否可信,容器环境是否安全(如主机是否安全、Docker程序配置是否安全)。


运营过程:此过程中,除安全监控、实施安全、应急响应、运营反馈等安全运营的闭环管理,针对容器运行安全,定期扫描容器运行环境安全基线(可参考CIS_Docker_Benchmark,比较有代表的工具Docker-bench-security),检测容器内及所依赖环境的进程、文件系统、磁盘、CPU等破坏容器隔离性和权限提升异常状态。

图2 容器全生命周期安全防护



展望

随着数字化转型进程的加快,容器技术进一步推动了业务的快速迭代,相应的容器安全也将成为热门领域之一。为迎接新型容器技术的安全挑战,我们不仅要培养懂容器、懂安全的复合型人员,也要不断探索针对容器新型攻击的防御,来保障容器云的安全运营和容器云安全体系的建设。


作者 | 丁明明

视觉 | 王朋玉

统筹 | 郑    洁

继续滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存