得物容器安全技术探索与落地实践

    作者:匿名更新于: 2022-12-10 17:45:39

    大神带你学编程,欢迎选课

      总体指导方针。围绕“重检测、轻管控、快响应”的九字方针开展工作,在效率和安全之间寻求平衡,在为业务保驾护航的同时,尽可能小地影响业务。

      1、前言

      得物服务早期主要是运行在ECS上,随着容器技术的日趋成熟,容器在降本增效、易于部署、灵活性等方面的优势开始显现。目前,得物已基本完成全域容器化,容器已成为支撑得物技术发展的重要基础设施。

      随着基础设施发生变化,业务在集成、交付、编排等方面都会与过往存在明显的不同,同时会伴随新的安全风险。如何发现和应对这些新的安全风险,本文将从技术和实践两个角度与读者进行分享和交流。

      2、容器是基础设施

      容器化应用在大体上可以分为两部分:构建时、运行时。

      2.1 容器虚拟化技术与其他虚拟化技术的主要差别

      容器是典型的“操作系统级虚拟化”,它没有独立的虚拟硬件,也不需要安装guest OS,这是它跟其他虚拟化技术的主要区别。

      全虚拟化:在Server OS之上会有一层hypervisor来实现虚拟化,然后由hypervisor虚拟化出虚拟硬件,用户再在虚拟硬件之上安装guest OS。典型的像:vmware workstation、kvm。

      裸金属:没有Server OS,只有hypervisor。上电后,系统引导过了BIOS之后,将直接引导到hypervisor,将对硬件的控制权交由hypervisor,由hypervisor虚拟化出虚拟硬件,用户再在虚拟硬件之上安装guest OS。典型的像:vmware ESXi。

      操作系统级虚拟化:多个容器共用一个kernel,没有独立的虚拟硬件也不用安装guest OS,容器间通过cgroup以及namespace来分别实现资源限制(例如:将某个容器的cpu、内存的阈值限定住)和资源隔离(例如:不同容器内的应用程序都可以bind同一个端口、不同容器内的ps看到的进程列表都是从1开始。在容器内的应用程序看来,就好像自己独占这台机器一样)。典型的像:docker、lxc、openVZ。

      2.2 镜像结构

      1.Linux运行基础

      首先,需要先掌握两个基础知识:Linux的bootfs和rootfs

      Linux系统要启动运行,至少需要两个文件系统:

      bootfs:包含boot-loader、kernel、grub。bios过了之后bios会拉起内核(bootfs),并将对硬件的控制权转交给操作系统。用户一般不会去修改bootfs,但也有例外,例如用户自己编译内核并用新内核启动。

      rootfs:包含经典的Linux目录结构:

      不同的系统组件、应用程序、lib文件、配置文件,都是包含在rootfs中。不同的Linux发行版的区别,主要是集中在rootfs。

      2.镜像文件结构基础

      对于同一台宿主机上的不同容器来说,容器间共享kernel,但各容器内包含的发行版以及应用程序却可以是不同的,也就是说:bootfs相同,但rootfs却是可以不同。我们通过dockerfile构建不同的镜像,实际上就是在控制rootfs的内容,让不同的容器运行不同的程序。

      docker hub上有很多基础镜像,我们可以基于基础镜像叠加我们自己的应用,然后再生成一个新的镜像。实际上当我们使用dockerfile去构建新的镜像时,就是在基础镜像的基础上再增加一层,也就是layer,这个layer里包含的是你的应用相关的内容,例如:你的应用程序、配置文件、环境变量等。

      3.剖析举例

      此处以一个docker镜像为例进行说明。

      先通过docker pull​命令拉取一个镜像,然后使用docker save命令将镜像保存为tar.gz文件,最后再解压tar.gz,得到镜像里的文件列表。

      拉取镜像:

      复制

      1.  M-C02G8E3AML7H:docker_image admin$ docker pull neuvector/scanner:latest

      2.  latest: Pulling from neuvector/scanner

      3.  213ec9aee27d: Already exists

      4.  cd33442680d5: Pull complete

      5.  867cbf496ec6: Pull complete

      6.  addb7fe17473: Pull complete

      7.  Digest: sha256:4f2679a8066dec6879d96504d11d880e08180a57fbe3f97176398bc049ee84eb

      8.  Status: Downloaded newer image for neuvector/scanner:latest

      9.  docker.io/neuvector/scanner:latest

      10.  M-C02G8E3AML7H:docker_image admin$

      保存并解压镜像:

      复制

          1.

      2.  M-C02G8E3AML7H:docker_image admin$ docker save neuvector/scanner:latest | gzip > test.tar.gz

      3.  M-C02G8E3AML7H:docker_image admin$ ls -lh

      4.  total 229504

      5.  -rw-r--r-- 1 admin staff 103M Nov 23 11:42 test.tar.gz

      6.  M-C02G8E3AML7H:docker_image admin$ tar -zxvf test.tar.gz

      7.  M-C02G8E3AML7H:docker_image admin$ ls -l

      8.  total 229528

      9.  drwxr-xr-x 5 admin staff 160 Nov 21 18:39 1288696addccc4013c5bcf61c1b6c38128a7214a0942976792918b51912d90f7

      10.  drwxr-xr-x 5 admin staff 160 Nov 21 18:39 4261ff25d711bed03d33a361482aeacff23027596d9d1c18f7223e1c4c87b42c

      11.  -rw-r--r-- 1 admin staff 3102 Nov 21 18:39 506daeaa7d07016f020a80cab3a6a8dc1a25551ff2a50e820183f0c255215ea4.json

      12.  drwxr-xr-x 5 admin staff 160 Nov 21 18:39 a1d413f6ea27d0e515f450d103ecec4a8e63564d47cbf156a09e118709399a5d

      13.  drwxr-xr-x 5 admin staff 160 Nov 21 18:39 f8ce18fff435609b86079966a73814c1fe976422930ad0e6b3d27725baff4bab

      14.  -rw-r--r-- 1 admin staff 444 Jan 1 1970 manifest.json

      15.  -rw-r--r-- 1 admin staff 100 Jan 1 1970 repositories

      16.  -rw-r--r-- 1 admin staff 108364451 Nov 23 11:42 test.tar.gz

      17.  M-C02G8E3AML7H:docker_image admin$

      分析镜像:

      从manifest.json中可以看出,该镜像一共由4层组成。

      第一层,即1288696addccc4013c5bcf61c1b6c38128a7214a0942976792918b51912d90f7/layer.tar解压出来的内容如下,可见都是最最基础的,诸如cp、基础库:(因篇幅原因,只展示该layer.tar解压出来的部分文件列表)

      复制

         1.

      2.  M-C02G8E3AML7H:1288696addccc4013c5bcf61c1b6c38128a7214a0942976792918b51912d90f7 admin$ tar -zxvf layer.tar

      3.  x bin/

      4.  x bin/busybox

      5.  x bin/cat

      6.  x bin/cp

      7.  x bin/date

      8.  x dev/

      9.  x etc/

      10.  x etc/motd

      11.  x etc/mtab

      12.  x etc/shadow

      13.  x etc/udhcpd.conf

      14.  x home/

      15.  x lib/

      16.  x lib/libc.musl-x86_64.so.1

      17.  x lib/libcrypto.so.1.1

      18.  x lib/libssl.so.1.1

      19.  x lib/libz.so.1

      20.  x lib/libz.so.1.2.12

      21.  x media/

      22.  x media/cdrom/

      23.  x media/floppy/

      24.  x media/usb/

      25.  x mnt/

      26.  x opt/

      27.  x proc/

      28.  x root/

      29.  x run/

      30.  x sbin/

      31.  x srv/

      32.  x sys/

      33.  x tmp/

      34.  x usr/

      35.  x usr/bin/

      36.  x usr/bin/awk

      37.  x usr/bin/basename

      38.  x usr/bin/bc

      39.  x usr/bin/beep

      40.  x usr/bin/blkdiscard

      41.  x usr/lib/

      42.  x usr/lib/libcrypto.so.1.1

      43.  x usr/lib/libssl.so.1.1

      44.  x usr/local/

      45.  x usr/local/bin/

      46.  x usr/local/lib/

      47.  x usr/local/share/

      48.  x usr/sbin/

      49.  M-C02G8E3AML7H:1288696addccc4013c5bcf61c1b6c38128a7214a0942976792918b51912d90f7 admin$

      第二层,即

      f8ce18fff435609b86079966a73814c1fe976422930ad0e6b3d27725baff4bab/layer.tar解压出来的内容如下:

      复制

      1.  M-C02G8E3AML7H:f8ce18fff435609b86079966a73814c1fe976422930ad0e6b3d27725baff4bab admin$ tar -zxvf layer.tar

      2.  x etc/

      3.  x etc/neuvector/

      4.  x etc/neuvector/certs/

      5.  x etc/neuvector/certs/internal/

      6.  x etc/neuvector/certs/internal/ca.cert

      7.  x etc/neuvector/certs/internal/cert.key

      8.  x etc/neuvector/certs/internal/cert.pem

      9.  x glibc-2.33-r0.apk

      10.  x licenses/

      11.  x licenses/EULA.pdf

      12.  x usr/

      13.  x usr/local/

      14.  x usr/local/bin/

      15.  x usr/local/bin/.nvcontainer

      16.  M-C02G8E3AML7H:f8ce18fff435609b86079966a73814c1fe976422930ad0e6b3d27725baff4bab admin$

      第三层,即f40081c28f00b0f31720fad1c99acaee5186173be08f060ac420f5358a870e16/layer.tar解压出来的内容如下:(因篇幅原因,只展示该layer.tar解压出来的部分文件列表)

      复制

         1.

      2.  M-C02G8E3AML7H:a1d413f6ea27d0e515f450d103ecec4a8e63564d47cbf156a09e118709399a5d admin$ tar -zxvf layer.tar

      3.  x etc/

      4.  x etc/ld.so.cache

      5.  x etc/nsswitch.conf

      6.  x etc/ssl/

      7.  x etc/ssl/certs/

      8.  x etc/ssl/certs/ca-cert-ACCVRAIZ1.pem

      9.  x etc/ssl/certs/ca-cert-AC_RAIZ_FNMT-RCM.pem

      10.  x lib/

      11.  x lib/ld-linux-x86-64.so.2

      12.  x lib64/

      13.  x lib64/ld-linux-x86-64.so.2

      14.  x usr/

      15.  x usr/share/ca-certificates/mozilla/vTrus_ECC_Root_CA.crt

      16.  x usr/share/ca-certificates/mozilla/vTrus_Root_CA.crt

      17.  M-C02G8E3AML7H:a1d413f6ea27d0e515f450d103ecec4a8e63564d47cbf156a09e118709399a5d admin$

      第四层,即4261ff25d711bed03d33a361482aeacff23027596d9d1c18f7223e1c4c87b42c/layer.tar解压出来的内容如下:

      复制

         1.

      2.  M-C02G8E3AML7H:4261ff25d711bed03d33a361482aeacff23027596d9d1c18f7223e1c4c87b42c admin$ tar -zxvf layer.tar

      3.  x etc/

      4.  x etc/neuvector/

      5.  x etc/neuvector/db/

      6.  x etc/neuvector/db/cvedb

      7.  x usr/

      8.  x usr/local/

      9.  x usr/local/bin/

      10.  x usr/local/bin/monitor

      11.  x usr/local/bin/scanner

      12.  x usr/local/bin/scannerTask

      13.  M-C02G8E3AML7H:4261ff25d711bed03d33a361482aeacff23027596d9d1c18f7223e1c4c87b42c admin$

      能够看到,从第一层到第三层解压出来的文件,都是基础bash、运行时依赖库、配置文件、证书等。第四层解压出来的,才是最终的应用程序。

      3.新技术带来的挑战

      相较于之前的ECS部署方式,容器部署方式带来了很多的优点:降本增效、资源隔离、资源限制、易于部署等。但新引入的基础设施,例如:镜像仓库、镜像/dockerfile、k8s宿主机、k8s、docker运行时、容器,也会随之带来新的安全风险,例如:镜像投毒、不安全镜像、k8s宿主机/k8s/docker不合规、k8s宿主机/k8s/docker高危漏洞、容器逃逸等。

      3.1 镜像投毒

      什么是镜像投毒?

      大家知道,docker有个好处就是“开箱即用”,比如说:我要一个mysql的环境,在没有docker之前呢,我们一般是找台机器,然后把mysql装上,改配置,最后启动。现在不用这样了,直接拉取一个mysql镜像,然后把容器运行起来,两条命令就可以搞定。是不是很高效?

      正是基于这种“开箱即用”带来的便利性,我们在下载到镜像后很少有人会去检查下这个镜像是不是安全的,大部分开发同学都是直接使用。黑客正是通过对开发同学的这种心理活动的揣摩和利用,会上传一些携带漏洞、病毒、后门、挖矿程序的镜像到dockerhub,这个过程就叫做镜像投毒。只要你下载了带毒的镜像并创建容器,就会在不知不觉中引入安全风险。举几个例子:

      例子一:黑客装个挖矿程序到镜像内,并设置成autorun,那么你在不知不觉中就成了黑客的矿机。

      例子二:黑客装个后门程序到镜像内,并设置成autorun,那么黑客就可以随时随地控制你的容器,更严重的甚至可以通过一些高危漏洞实现容器逃逸而进一步控制你的宿主机。

      想想都挺可怕。那怎么破呢?

      下载带OFFICIAL标志的,表明是经过官方认证的。同时做好常态化的镜像风险扫描工作,及时发现并清除安全风险。

      如果找不到带OFFICIAL标志的,则可以看STARS数,选择STARS数大的。

      3.2 不安全镜像

      镜像内可能会携带弱点:漏洞、病毒/木马/后门、敏感信息泄漏、弱口令、dockerfile不合规等安全风险。

      有些弱点是系统自带的(例如:python run-time漏洞),有些弱点是我们自己无意间引入的(例如:使用了不安全的fastjson版本、被投毒镜像携带的病毒、敏感信息明文等),有些漏洞是新报出来的。

      3.3 k8s宿主机/k8s/docker不合规

      什么是合规?可以理解成“符合规范”,符合国家(国标)或行业(行标)对网络安全的规范要求。

      k8s宿主机,基本上采用的都是Linux系统,所以可以采用Linux等级保护L2/L3的检测规范。

      k8s/docker,采用CIS benchmark居多。

      docker参考:https://www.cisecurity.org/benchmark/docker

      k8s参考:https://www.cisecurity.org/benchmark/kubernetes

      3.4 k8s宿主机/k8s/docker高危漏洞

      是软件就难免会有漏洞,不管是OS kernel,亦或是组件库,还是应用程序。

      k8s&docker的安全漏洞:

      3.5 容器逃逸

      什么是逃逸?简单来说就是:容器获得了它本不该拥有的容器宿主机系统资源的访问权限。

      容器内的应用,由于Linux kernel namespace机制的限制,是访问不到宿主机的系统资源(进程、/proc、网络信息、文件系统等)的。但通过一些漏洞或者错误配置,则可以实现容器逃逸,等同于提权,危害可想而知。

      4.如何应对这些新的安全挑战

      大体上可以分为两部分:构建时、运行时。

      4.1 构建时

      这个阶段覆盖的资产主要有镜像仓库以及镜像。

      主要的目的是要确保:

      (1)无高危且易于利用的漏洞

      (2)无病毒/后门/木马

      (3)合规

      (4)无敏感信息泄漏(例如明文密码、token)

      (5)无弱口令配置

      落地实践:

      镜像扫描器与镜像仓库联动。当镜像PUSH时,会对镜像进行实时扫描。

      对镜像仓库上的所有镜像进行日常常态化扫描。

      安全核心能力方面:

      提供漏洞扫描能力。支持对web漏洞、系统漏洞的检测。

      提供病毒/木马/后门扫描能力。支持对Linux病毒、Windows病毒的检测。

      提供敏感信息检测能力。

      提供弱口令检测能力。

      提供IaC检测能力。支持对dockerfile、k8s yaml进行安全扫描。

      4.2 运行时

      这个阶段覆盖的资产主要有k8s宿主机、k8s&docker、容器。

      主要的目的是要确保:

      1、能加固的都尽量加固掉。包括:漏洞、不合规项、弱口令

      2、要能及时发现黑客的入侵行为。

      为什么是这两个目的?黑客没来攻击之前,我们要尽可能地把系统加固得更牢固,抬高黑客的攻击难度;倘若还是被黑客突破进来了,那黑客肯定会执行些命令,黑客一般来说会有以下几个渗透攻击阶段的典型行为,通过事先对黑客进行行为建模,只要某个用户在系统上的行为落在“黑客行为模型”内,就判定为入侵行为。

      运行时整体框架:

      会在每台k8s宿主机上,以daemonset方式启动一个安全容器并挂在k8s下。这个安全容器内部跑两个引擎:

      引擎一:基线检测引擎。它主要负责漏洞扫描、合规检测、本地爆破,最终目的是为了给运营同学进行系统加固提供依据。同时,该引擎也支持事中SCA(软件成份分析),能够根据软件供应链漏洞快速梳理出受影响的容器资产,以应对频发的软件供应链安全事件。

      引擎二:入侵检测引擎。它主要负责采集系统上的关键指标(进程信息、进程树、文件变更事件、网络连接、fd、历史命令、用户登录等信息),然后由平台侧的Flink任务进行预处理,最后进模型匹配。最终目的是为了发现黑客入侵行为,为及时止血提供线索。

      由于是部署在k8s宿主机上,需要安全容器具备较高的稳定性,避免出现资损。

      稳定性方面:

      以平行容器方式托管在k8s下,通过Linux namespace和cgroup来实现资源隔离和资源限制。cpu使用率通过k8s睿频技术进行动态调配,例如:reqeust=0.02c limit=2c,安全容器默认只占0.02c,当业务容器不使用cpu时,则此时安全容器最多可以使用2c的cpu;而当业务容器需要cpu资源时,安全容器会主动释放cpu时间片。

      版本更新借助k8s框架实现。灰度升级时使用nodeSelect+打标,实现分批升级。

      完善监控指标,触发门限后进行告警。

      定期进行稳定性演练。

      5、思考和总结

      总体指导方针。围绕“重检测、轻管控、快响应”的九字方针开展工作,在效率和安全之间寻求平衡,在为业务保驾护航的同时,尽可能小地影响业务。

      安全能力实战化。攻防是一个持续博弈和对抗的过程,每年都会有新的威胁、新的攻击手法出现,通过定期的实战化演练(例如:红蓝对抗、白帽渗透测试)来检验安全能力的水位。跳出容器来看容器,多方思考和学习,才能拿到理想的结果。未知攻,焉知防​;其实反过来看,也同样成立:未知防,焉知攻​。最终需要做到既知攻,亦知防,才能把事情做到自己认知范围内的最好程度。​

      来源: 得物技术

        >>>>>>点击进入编程语言专题

编程语言 更多推荐

课课家教育

未登录