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

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

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

在本系列中,我们介绍了各种安全层,这些安全层不仅可以将容器与主机上的其他进程隔离开来,还可以将容器与其底层主机隔离开来。在这篇文章中,我们将讨论 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 配置文件进行低级容器强化的另一种选择。

相关推荐

oracle数据导入导出_oracle数据导入导出工具

关于oracle的数据导入导出,这个功能的使用场景,一般是换服务环境,把原先的oracle数据导入到另外一台oracle数据库,或者导出备份使用。只不过oracle的导入导出命令不好记忆,稍稍有点复杂...

继续学习Python中的while true/break语句

上次讲到if语句的用法,大家在微信公众号问了小编很多问题,那么小编在这几种解决一下,1.else和elif是子模块,不能单独使用2.一个if语句中可以包括很多个elif语句,但结尾只能有一个...

python continue和break的区别_python中break语句和continue语句的区别

python中循环语句经常会使用continue和break,那么这2者的区别是?continue是跳出本次循环,进行下一次循环;break是跳出整个循环;例如:...

简单学Python——关键字6——break和continue

Python退出循环,有break语句和continue语句两种实现方式。break语句和continue语句的区别:break语句作用是终止循环。continue语句作用是跳出本轮循环,继续下一次循...

2-1,0基础学Python之 break退出循环、 continue继续循环 多重循

用for循环或者while循环时,如果要在循环体内直接退出循环,可以使用break语句。比如计算1至100的整数和,我们用while来实现:sum=0x=1whileTrue...

Python 中 break 和 continue 傻傻分不清

大家好啊,我是大田。...

python中的流程控制语句:continue、break 和 return使用方法

Python中,continue、break和return是控制流程的关键语句,用于在循环或函数中提前退出或跳过某些操作。它们的用途和区别如下:1.continue(跳过当前循环的剩余部分,进...

L017:continue和break - 教程文案

continue和break在Python中,continue和break是用于控制循环(如for和while)执行流程的关键字,它们的作用如下:1.continue:跳过当前迭代,...

作为前端开发者,你都经历过怎样的面试?

已经裸辞1个月了,最近开始投简历找工作,遇到各种各样的面试,今天分享一下。其实在职的时候也做过面试官,面试官时,感觉自己问的问题很难区分候选人的能力,最好的办法就是看看候选人的github上的代码仓库...

面试被问 const 是否不可变?这样回答才显功底

作为前端开发者,我在学习ES6特性时,总被const的"善变"搞得一头雾水——为什么用const声明的数组还能push元素?为什么基本类型赋值就会报错?直到翻遍MDN文档、对着内存图反...

2023金九银十必看前端面试题!2w字精品!

导文2023金九银十必看前端面试题!金九银十黄金期来了想要跳槽的小伙伴快来看啊CSS1.请解释CSS的盒模型是什么,并描述其组成部分。...

前端面试总结_前端面试题整理

记得当时大二的时候,看到实验室的学长学姐忙于各种春招,有些收获了大厂offer,有些还在苦苦面试,其实那时候的心里还蛮忐忑的,不知道自己大三的时候会是什么样的一个水平,所以从19年的寒假放完,大二下学...

由浅入深,66条JavaScript面试知识点(七)

作者:JakeZhang转发链接:https://juejin.im/post/5ef8377f6fb9a07e693a6061目录...

2024前端面试真题之—VUE篇_前端面试题vue2020及答案

添加图片注释,不超过140字(可选)...

今年最常见的前端面试题,你会做几道?

在面试或招聘前端开发人员时,期望、现实和需求之间总是存在着巨大差距。面试其实是一个交流想法的地方,挑战人们的思考方式,并客观地分析给定的问题。可以通过面试了解人们如何做出决策,了解一个人对技术和解决问...