容器运行时安全

容器运行时安全

运行时安全是在容器运行时通过检测和防止恶意行为来提供主动保护,整个容器生命周期中的最后一道安全屏障。

其核心思想是监控并限制容器中高危的行为,缩小容器进程的能力和权限。

容器本身是利用了 Namespace 和 Cgroup 技术,将容器和宿主机之间的资源进行隔离和限制。

Namespace 是 Linux 提供的一种内核级别的环境隔离功能,主要用途是对容器提供资源的访问隔离。Cgroup 是限制容器对资源的占有。

虽然这种隔离限制从资源层面实现了对容器和宿主机之间的环境独立,宿主机的资源对容器不可见。但是这种方式并没有达到真正意义上的安全隔离,由于容器的内核和宿主内核共享,一旦容器中通过恶意行为进行一些高危的操作权限,

或者是利用内核漏洞,往往就能突破这种资源上的隔离,造成容器逃逸,重新危害到宿主机及上面运行的其他容器。

目前 Linux 内核提供一系列的安全能力可以对这些攻击行为进行有效防护。结合内核安全技术的能力,这些技术的作用范围可以简单地分为两种:一种限制是限制行为本身,另一种则是限制行为作用的对象范围。

Capabilities 和 Seccomp

在Linux系统中 Root 用户作为超级用户拥有全部的操作权限,以 Root 身份运行容器,相当于将容器资源限制大门的钥匙交给容器本身,这是十分危险的。但是以非 Root 身份在后台运行容器的话,由于缺少权限容器中的应用进程容易处处受限。

为了适用这种复杂的权限需求,Linux 细化了 Root 权限的管控能力,将超级用户的权限分解为细粒度的单元,称为 Capabilities 。例如, CAP_CHOWN 允许用户对文件的 UID 和 GID 进行任意修改,即执行 chown 命令。

几乎所有与超级用户相关的特权都被分解成单独的 Capability,可以分别启用或者禁用。这种权限机制的访问控制,控制容器运行所需的 Capabilities 范围,可以有效切断容器中攻击者的行为操作。即使容器攻击者取得了 Root 权限,由于不能获得主机的完全的操作权限,进一步限制了攻击对宿主机的破坏。

但是基于 Capabilities 的权限访问管理,有时候并不能很好地限制容器的操作系统。例如, SYS_ADMIN 管理了诸多系统调用的访问权限。一旦应用进程因为需要进行 sethostname 这样的操作而在容器中开启了 SYS_ADMIN 组的 Capabilities,那么也就让容器具有了 mount 这类可以挂载系统资源的操作权限,导致容器存在逃逸的风险。

Seccomp (Secure Computing Mode)安全计算模式同样也是一种 Linux 内核提供的安全特性,允许用户使用可配置的策略过滤系统调用,该策略使用 BPF 规则实现,从而使 Seccomp 可以对任意的系统调用及其参数进行过滤。

MAC

Namespace 的隔离机制让宿主机上的资源对容器不可见,但是没有限制容器中进程的访问权限,资源访问权限的权利是由 Linux DAC(Discretionary Access Control,自主访问控制,简称 DAC)机制来完成的,主要依赖进程的 uid 和 gid 进行管理。

一旦容器中的攻击者突破 Namespace 的界限,往往就可以对容器外的资源进行访问。而解决这一安全风险的关键就是强制访问控制(Mandatory Access Control)MAC 。其中最熟知的 MAC 访问控制安全模块是 SELinux、AppArmor等。

DAC通常允许授权用户自主改变客体的访问控制属性,可以指定其他用户是否有权访问该客体。然而,DAC 机制只约束了用户、同用户组内的用户、其他用户对文件的可读、可写、可执行权限,这对系统的保护作用非常有限。

Linux 系统中所有内容都是以文件的形式保存和管理的,即一切皆文件。

为了克服 DAC 这种脆弱性,出现了 MAC 机制,其基本原理是利用配置的安全策略来控制对客体的访问,且这种访问不被单个程序和用户所影响。

SELinux

Security-Enhanced Linux 是由美国国家安全局(NSA)联合其他的安全机构(如SCC公司)共同开发的一套 MAC 安全认证机制。

Selinux 规定了每个对象(程序、文件和进程等)都有一个安全上下文(Security Context),它依附于每个对象身上,包含了许多重要的信息。包括 Selinux 用户、角色、类型和级别等。

管理员可以通过定制安全策略来定义上下文,从而定义哪种对象具有什么权限。当一个对象需要执行某个操作时,系统会按照该对象以及该对象要操作的对象的安全上下文所定制的安全策略来检查相对应的权限。如果全部权限都符合,系统就会允许该操作,否则将阻断这个操作。

SELinux 与 DAC

在启用了 SELinux 的 Linux 操作系统中,SELinux 并不是取代传统的 DAC 机制。当某个对象需要执行某个操作时,需要先通过 DAC 机制的检测,再由 SELinux 定制的安全策略来检测。如果 DAC 规则拒绝访问,则根本无需使用 SELinux 策略。只有通过 DAC 和 SELinux 的双重权限检查确认之后,才能执行操作。

容器与 SELinux

容器在默认配置下是没有开启 SELinux 功能的,需要管理者修改 Docker 守护进程中的参数配置进行开启。

AppArmor

AppArmor 的目的是希望开发一个比 SELinux 更简单易用的访问控制模块。

RedHat 旗下的Linux发行版都预装提供 SELinux 设置,包括 RHEL、 Centos 、Fedora。而Apparmor 安装在 Debian、Ubuntu等发行版上。

与 SELinux 不同,AppArmor 是作为 DAC 机制的补充,用于限制指定目标程序的资源访问权限,例如是否允许读/写某个特定的目录/文件、打开/读/写网络端口以及是否具备某类 Linux Capabilities 等。为了简单易用,Apparmor使用文件名(路径名)作为安全标签,而SELinux使用文件的 inode 作为安全标签。在文件系统中,只有inode才具有唯一性,因此相比于 SELinux,通过改名等方式,AppArmor 存在被绕过的风险。

LSM

不管是 SELinux 还是 AppArmor,其实都是 Linux 安全模块(Linux Security Module)LSM,都是基于 LSM 框架。是一种 Linux 操作系统内核提供的一种安全机制,来完成对进程对 Linux 资源访问权限的判断。LSM是和内核代码一起编译在内核文件中,并且只能在系统启动时就进行初始化。

eBPF 与 LSM 模块

相较于 LSM 框架,eBPF 提供了一种更加简便安全的方式在 Linux 内核中运行自定义的代码。通过编写内核模块来改变或扩展内核行为,往往需要足够的内核编程知识,并且在编写使用过程中需要十分谨慎,以免因为一些疏忽带来内核代码崩溃的问题,甚至留下攻击者可以利用的漏洞。因此为了保障内核安全性,往往内核模块的开发以及内核新版本的发布,都需要长时间的分析测试。

而 eBPF 程序的开发则不需要通过复杂的内核编译,只需要引入相关结构体的头文件申明,这就给 eBPF 程序的开发降低了难度。同时 eBPF 在安全性保证上提供了一道有效的屏障—— eBPF 验证器:在整个 eBPF 的使用过程中,内核会在加载 eBPF 程序时对 eBPF 程序进行分析验证,保证 eBPF 程序不会造成内核崩溃等问题。

更具有优势的一点是,eBPF 程序是可以动态地从内核中加载或删除,而不像 LSM 模块需要重启系统才能进行模块加载,完全可以做到不打断任何已经存在的进程。

eBPF 与容器安全

eBPF 提供了一种便利的可基于系统或程序事件高效安全执行特定代码的通用能力,并且它可检测的事件覆盖了系统的各个方面(如下图所示),提供了丰富的可观察信息,甚至在 Linux 5.7 版本后 eBPF 程序可以插入 LSM hook 点。

ebpf

对于容器环境来说,所有运行在一台机器上的容器都和主机共享内核,内核了解主机上运行的所有应用代码。eBPF 的 Hook 点可以说是遍布内核的各个角落,这对于容器安全的检测和防护是很大的助力,方便了对容器中正在进行的操作的分析和判断,近些年来有许多利用这项新技术来解决一些容器安全问题的工具。

当前这类安全上的工具主要可以分为两类:一类是确保网络活动的安全,eBPF 最初就是用于网络数据包过滤的技术,可以在网络驱动中尽可能早的位置提供最优的数据包处理能力,过滤并丢弃恶意或非预期的流量以及防范 DDOS 攻击等。而另一类则是检测恶意行为,确保应用程序在运行时的行为安全。例如利用 eBPF 同样可以在系统调用的入口处插入检测过滤程序,但是相比于 Seccomp 更强大的地方在于,eBPF 程序可以对其中的指针参数进行解引用,这也就方便了更进一步的行为分析。

下表列举了当前比较有名的基于 eBPF 开发的安全工具:

tools

容器运行时安全的未来:

当前云原生的技术大多数被服务于 Web 应用的相关业务,此类业务往往把性能要求放在较为靠前的位置,对于设备上选用的安全加固技术都会有性能方面的考量。而 eBPF 的出现为容器安全带来了一种能够动态、轻量、无感知的提升防御能力的方式。其全面的观测能力,可以轻松地监控到容器安全可观测性的四个黄金信号:进程执行、网络套接字、文件访问和七层网络身份,保证了安全检测的全面性。

在未来的发展过程中,eBPF 的相关应用将是容器运行时安全最重要的助力。同时,不可忽视的是对低版本内核系统上的安全防护,目前并在未来很长的一段时间内,大多数的主机服务器上仍然将运行着 Linux 3.* 以及 4.* 的系统。对于这些系统来说,Seccomp、LSM 模块等内核安全机制依旧是保障容器安全不可或缺的部分。


最后修改 December 25, 2024: 菜单更新 (a57fa7d)