百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

【容器安全系列Ⅴ】- Linux强制访问控制:AppArmor 和 SELinux

wptr33 2024-12-11 17:29 18 浏览

在本系列中,我们介绍了各种安全层,这些安全层不仅可以将容器与主机上的其他进程隔离开来,还可以将容器与其底层主机隔离开来。在这篇文章中,我们将讨论 AppArmor 和 SELinux 如何在我们之前讨论过的其他隔离层之外提供额外的限制。

强制访问控制系统

AppArmor 和 SELinux 是强制访问控制 (MAC) 系统的示例。这些系统与其他安全控制(通常称为自主访问控制(DAC)系统)的不同之处在于,用户通常无法更改其操作。

文件权限是 DAC 系统的一个示例。文件的所有者可以调整其权限,以允许主机上的任何人修改它。使用 MAC 系统时,用户可能无法修改对他们拥有的资源施加的约束。这些限制甚至包括 root 用户,尽管系统上的 root 用户只需禁用整个 MAC 系统即可绕过此限制。Linux 中的 MAC 系统允许你限制对各种系统资源的访问,以便即使是其他特权进程也无法访问它们。

虽然可以在任何 Linux 主机上同时使用 AppArmor 或 SELinux,但通常只启用其中一个MAC策略 ,这因不同发行版而异。默认情况下,Debian 衍生系统使用 AppArmor,而基于 Red Hat 的系统则使用 SELinux。

AppArmor

AppArmor 通过定义可应用于主机上运行的进程的不同配置文件来实现其控制能力。这些配置文件可以限制对许多资源的访问,包括文件、网络流量和 Linux capabilities。

在安装了 AppArmor 的系统上,我们可以开始探索如何使用 sudo aa-status 命令来使其发挥作用。这将显示有关 AppArmor 配置和状态的信息。

aa-status 的输出

从这个输出中,我们可以看到几个有趣的信息:

  • AppArmor 已加载并正常工作。
  • 系统上定义了 34 个配置文件。
  • 目前,没有进程具有启用的 AppArmor 配置文件。

从容器化的角度来看,配置文件列表中最有趣的部分是 docker-default 。默认情况下,此配置文件在 Docker 中默认用于提供一些保护,且不会影响应用程序兼容性。但是,这意味着它并没有像它可能的那样被锁定,因此有必要为需要额外保护的应用程序创建更严格的配置文件。

为了演示当进程获取活动 AppArmor 配置文件时会发生什么,我们可以通过 docker run -d nginx 启动一个新的 Docker 容器,然后运行 aa-status 命令。可以看到,我们现在有五个进程(由我们的容器启动)定义了一个配置文件,还有五个进程处于强制模式,这意味着 AppArmor 将根据为每个进程定义的配置文件限制它们的操作。

应用于 NGINX 的 Docker 默认 AppArmor 配置文件

现在我们已经了解了 AppArmor 的基础知识,让我们看看可以使用自定义 AppArmor 配置文件执行哪些操作,以及如何将其应用于 Docker 容器。

使用 AppArmor 的自定义配置文件

AppArmor 允许你控制许多 Linux 资源,包括网络和文件访问。为了通过一个简单的示例来演示这一点,我们可以创建一个配置文件来阻止对容器内/etc目录的写入访问,即使运行容器的用户是 root

首先,我们将创建一个最小的配置文件来实现我们的目标。

#include <tunables/global>

profile docker-block-bin flags=(attach_disconnected, mediate_deleted) {

  #include <abstractions/base>

  file,

  deny /etc/** wl,

}

这里的关键行是 deny /etc/** wl,它阻止对/etc和任何子目录的写入访问。我们将此配置文件写入 /etc/apparmor.d/containers/docker-block-etc ,然后使用命令 sudo apparmor_parser -r /etc/apparmor.d/containers/docker-block-etc 将其加载到内核中。一旦准备就绪,我们就可以用 Docker 进行测试了。

我们可以创建一个新容器并使用 --security-opt 标志将我们的 etc 阻止配置文件应用于它:

docker run --rm -it --name block-bin --security-opt "apparmor=docker-block-etc" ubuntu:22.04 /bin/bash
然后,我们可以从容器内部尝试向/etc写入文件.输出证明,尽管我们是 root 用户,但我们无无法写入该目录。

自定义 AppArmor 配置文件阻止写入 /etc

如果您需要为 Docker 容器开发更复杂的配置文件,有一些工具可以帮助简化该过程,例如 Bane。Bane 的优点是自动为所有 Docker 容器添加基本限制。它还为配置文件规范提供了简化的语法。

SELinux

SELinux 在 Linux 方面有着悠久的历史。美国国家安全局最初在 2000 年将其作为 Linux 内核的一系列补丁实施。从那时起,Linux 生态系统中的开发仍在继续,如今,SELinux 默认用于基于 Red Hat 的发行版等。

与 AppArmor 相比,SELinux 采用了完全不同的安全方法。SELinux 没有将离散配置文件应用于进程,而是标记 Linux 资源(例如文件和端口),并根据每个资源的标签和尝试访问资源的进程的属性来限制对它们的访问。

在安装了 SELinux 的系统上,我们可以使用 sestatus 命令来查看它的配置方式。

sestatus 的输出

此命令返回有关如何在此主机上配置 SELinux 的关键信息。

第一行表示已启用 SELinux。Loaded policy name 告诉我们我们在 targeted 模式下运行(这意味着 SELinux 将应用于主机上的分发提供商(例如 Red Hat)选择的特定进程),而不是 mls 模式,后者更严格,并且对每个进程施加限制。通常,mls 模式不适用于通用系统,因为管理所有进程的标记和权限很复杂。

下一行是:Current mode: enforcing.在这里,可能的选项是:enforcing、 permissive disabled。permissive模式对于设置 SELinux 很有用,因为它不会阻止操作。相反,它将记录在系统处于enforcing模式时可能发生的任何拒绝。

现在我们已经注意到在此主机上启用了 SELinux,我们可以探索有关当前配置的更多详细信息。运行 sudo semanage login -l 将向我们展示如何配置 SELinux 以处理标准用户进程。

semanage login -l 的输出

从这个输出中,我们可以看到 SELinux 认为普通用户(用__default__表示)和 root 用户是不受限制的,这意味着它不会对他们施加限制。

您可以使用标准系统工具和-Z开关来查看 SELinux 使用的标签。例如,pf -efZ 将显示有关应用于不同进程的标签的信息。在下面的示例中,我们可以看到 dockerd containerd 进程的标签应用了 container_runtime_t 类型,并且标准用户使用的 bash 和 ssh 进程具有 unconfined_t 类型。

进程上的 SELinux 属性

我们还可以使用类似 ls -alZ .

文件上的 SELinux 属性

容器 SELinux 策略

在 Fedora 或 Red Hat 等 Linux 发行版下运行 Docker 时,通用的 SELinux 策略将应用于所有新容器。与 Docker 的默认 AppArmor 配置文件一样,此常规配置文件必须在提供的保护中做出权衡,因为它将相同的策略应用于每个容器。

要查看此策略的效果,我们可以运行类似 docker run --rm -it --name home_container -v /home/rorym:/hosthome fedora /bin/bash 启动名为“home_container”的新容器,该容器将我们的主目录挂载到容器中。如果我们尝试在容器内的 /hosthome 目录中创建一个文件,即使我们以 root 用户身份运行,我们也会被阻止。

SELinux 阻止对主机上 /home 的访问

为了确认 SELinux 是否阻止了访问,我们可以运行同一个容器并将 --security-opt label:disable 添加到命令中,这实际上禁用了该容器的 SELinux。如果我们随后尝试在 /hosthome 目录中创建一个文件,我们可以看到它是成功的。

禁用了 SELinux 的容器

如果我们想创建一个自定义的 SELinux 策略来允许我们访问我们的主目录,一种选择是使用 udica 之类的工具。此工具分析有关正在运行的容器的数据,以创建 SELinux 策略,然后可以加载和使用该策略。

首先,让我们检查我们的容器,并通过运行命令 docker inspect home_container | sudo udica home_container 将结果传递给 udica。完成此操作后,udica 将指示我们加载新的 SELinux 模块(它已创建),然后在指定新策略的同时重新启动我们的容器。使用此策略启动容器后,我们可以看到可以根据需要写入主目录。

通过UDICA定制标签的容器

结论

强制访问控制系统可以为容器提供额外的保护层。但是,它还需要努力学习如何有效地使用它们,并且自定义它们以大规模使用容器是一项艰巨的任务。因此,组织通常需要评估其风险状况,以确定使用它们是否有意义。在本系列的下一部分中,我们将介绍使用 seccomp 配置文件进行低级容器强化的另一种选择。

相关推荐

redis的八种使用场景

前言:redis是我们工作开发中,经常要打交道的,下面对redis的使用场景做总结介绍也是对redis举报的功能做梳理。缓存Redis最常见的用途是作为缓存,用于加速应用程序的响应速度。...

基于Redis的3种分布式ID生成策略

在分布式系统设计中,全局唯一ID是一个基础而关键的组件。随着业务规模扩大和系统架构向微服务演进,传统的单机自增ID已无法满足需求。高并发、高可用的分布式ID生成方案成为构建可靠分布式系统的必要条件。R...

基于OpenWrt系统路由器的模式切换与网页设计

摘要:目前商用WiFi路由器已应用到多个领域,商家通过给用户提供一个稳定免费WiFi热点达到吸引客户、提升服务的目标。传统路由器自带的Luci界面提供了工厂模式的Web界面,用户可通过该界面配置路...

这篇文章教你看明白 nginx-ingress 控制器

主机nginx一般nginx做主机反向代理(网关)有以下配置...

如何用redis实现注册中心

一句话总结使用Redis实现注册中心:服务注册...

爱可可老师24小时热门分享(2020.5.10)

No1.看自己以前写的代码是种什么体验?No2.DooM-chip!国外网友SylvainLefebvre自制的无CPU、无操作码、无指令计数器...No3.我认为CS学位可以更好,如...

Apportable:拯救程序员,IOS一秒变安卓

摘要:还在为了跨平台使用cocos2d-x吗,拯救objc程序员的奇葩来了,ApportableSDK:FreeAndroidsupportforcocos2d-iPhone。App...

JAVA实现超买超卖方案汇总,那个最适合你,一篇文章彻底讲透

以下是几种Java实现超买超卖问题的核心解决方案及代码示例,针对高并发场景下的库存扣减问题:方案一:Redis原子操作+Lua脚本(推荐)//使用Redis+Lua保证原子性publicbo...

3月26日更新 快速施法自动施法可独立设置

2016年3月26日DOTA2有一个79.6MB的更新主要是针对自动施法和快速施法的调整本来内容不多不少朋友都有自动施法和快速施法的困扰英文更新日志一些视觉BUG修复就不翻译了主要翻译自动施...

Redis 是如何提供服务的

在刚刚接触Redis的时候,最想要知道的是一个’setnameJhon’命令到达Redis服务器的时候,它是如何返回’OK’的?里面命令处理的流程如何,具体细节怎么样?你一定有问过自己...

lua _G、_VERSION使用

到这里我们已经把lua基础库中的函数介绍完了,除了函数外基础库中还有两个常量,一个是_G,另一个是_VERSION。_G是基础库本身,指向自己,这个变量很有意思,可以无限引用自己,最后得到的还是自己,...

China&#39;s top diplomat to chair third China-Pacific Island countries foreign ministers&#39; meeting

BEIJING,May21(Xinhua)--ChineseForeignMinisterWangYi,alsoamemberofthePoliticalBureau...

移动工作交流工具Lua推出Insights数据分析产品

Lua是一个适用于各种职业人士的移动交流平台,它在今天推出了一项叫做Insights的全新功能。Insights是一个数据平台,客户可以在上面实时看到员工之间的交流情况,并分析这些情况对公司发展的影响...

Redis 7新武器:用Redis Stack实现向量搜索的极限压测

当传统关系型数据库还在为向量相似度搜索的性能挣扎时,Redis7的RedisStack...

Nginx/OpenResty详解,Nginx Lua编程,重定向与内部子请求

重定向与内部子请求Nginx的rewrite指令不仅可以在Nginx内部的server、location之间进行跳转,还可以进行外部链接的重定向。通过ngx_lua模块的Lua函数除了能实现Nginx...