AppArmor

简要概述

AppArmor 是一个 Linux 内核安全模块,用于补充系统用户和组的权限,将程序限制在一组有限的资源中。

它通过调整配置文件以允许特定程序或容器所需的访问,如 Linux 权能字、网络访问、文件权限等。每个配置文件都可以在强制(enforcing)模式(阻止访问不允许的资源)或 投诉(complain)模式(仅报告冲突)下运行。

有三个主要版本,分别是 2.x 系列(旧版本但仍受支持)、3.x 系列(当前版本)和 4.x 系列(开发中)

快速开始

确认环境

查看宿主上是否启用:

cat /sys/module/apparmor/parameters/enabled

查看宿主上规则加载:

apparmor_status

目录结构

AppArmor 工具的配置在 /etc/apparmor/ 目录下。

AppArmor 策略存储在 /etc/apparmor.d/ 目录下,各目录用途如:

目录 说明
/etc/apparmor.d/abstractions/ 包含用于构建 AppArmor 抽象配置的文件,可在多个配置文件中重复使用,以提高可维护性和复用性
/etc/apparmor.d/apache2.d/ 包含与 Apache2 Web 服务器相关的 AppArmor 配置文件
/etc/apparmor.d/cache/ 预编译的二进制策略文件
/etc/apparmor.d/disable/ 包含一些符号链接,这些链接指向需要禁用的配置文件,禁用配置文件意味着它们不会对系统中的进程生效
/etc/apparmor.d/force-complain/ 包含一些符号链接,这些链接指向需要强制使用 complain 模式的配置文件,在该模式中,违反策略的行为将被记录,但不会导致实际的限制
/etc/apparmor.d/libvirt/ 包含与 libvirt 虚拟化工具相关的 AppArmor 配置,用来限制与虚拟机和容器相关的进程的权限
/etc/apparmor.d/local/ 本地管理员创建的自定义的配置文件通常存储在这个目录中,这样可以确保不会与系统提供的配置文件发生冲突
/etc/apparmor.d/namespaces/ TODO;
/etc/apparmor.d/pam/ 包含与 PAM 相关的 AppArmor 配置
/etc/apparmor.d/tunables/ TODO;

具体取决于你的操作系统供应商和版本,你的系统可能具有上述目录中的一些或全部。策略的编写是通过特有的语法 AppArmor_Core_Policy_Reference 为各个应用编写成配置文件,然后使用 apparmor_parser 编译并加载到内核中。

限制本地应用测试

编写规则

cat << EOF >> /etc/apparmor.d/local/usr.bin.touch
#include <tunables/global>

profile /usr/bin/touch {
  #include <abstractions/base>

  /tmp/** r,
}
EOF

这个规则说明禁止 /usr/bin/touch 在 “/tmp/” 目录下写,仅允许读。

生效规则

apparmor_parser --add /etc/apparmor.d/local/usr.bin.touch --verbose

或者替换现有规则

apparmor_parser --replace /etc/apparmor.d/local/usr.bin.touch --verbose

只有通过以上两个命令才可真正生效规则。

这个时候可以通过 apparmor_status 查看当前系统所有生效的规则列表。

测试规则

root@limiqi-dell-01:/etc/apparmor.d/local# touch /tmp/hello2.txt
touch: cannot touch '/tmp/hello2.txt': Permission denied
root@limiqi-dell-01:/etc/apparmor.d/local#

创建文件 “/tmp/hello2.txt” 此时被拒绝。

限制 Kubernetes 应用测试

编写规则

cat << EOF >> /etc/apparmor.d/local/kubernetes-app-demo-1
profile kubernetes/app-demo-1 {
  file,
  deny /root/** w,
}
EOF

这个规则说明禁止往 “/root/*” 目录下写文件。

生效规则

第一部分同 限制本地应用测试 / 生效规则

第二部分为启用的 Pod 添加注解,格式为:

container.apparmor.security.beta.kubernetes.io/<container_name>: <value>

其中 “<container_name>” 对应 Pod 内需要启用的容器名,如有多个可单独配置,“value” 可配置以下三个值:

value 说明
runtime/default 指默认运行时配置文件,见默认规则
localhost/<profile_name> 使用本地自定义规则,该宿主上必须存在,否则无法启动 Pod
unconfined 这相当于为容器禁用 AppArmor

对应以上规则使用 “kubernetes/app-demo-1” 的规则为:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    container.apparmor.security.beta.kubernetes.io/nginx: localhost/kubernetes/app-demo-1
  name: nginx

测试规则

root@limiqi-dell-01:/etc/apparmor.d/local# kubectl exec -i -t nginx /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo "hello world" > /root/test.txt
/bin/sh: can't create /root/test.txt: Permission denied
/ #
/ # ^C
command terminated with exit code 130
root@limiqi-dell-01:/etc/apparmor.d/local#

常见问题

查找使用默认 containerd 的 AppArmor

由于 containerd 在宿主上生成的 profile 名称为 “cri-containerd.apparmor.d” 所以可以通过查找即可知道哪些容器使用了:

apparmor_status | grep cri-containerd.apparmor.d
   cri-containerd.apparmor.d
   /usr/local/bin/kube-apiserver (6428) cri-containerd.apparmor.d
   /usr/local/bin/kube-controller-manager (6759) cri-containerd.apparmor.d
   /coredns (18598) cri-containerd.apparmor.d
   /metrics-server (19028) cri-containerd.apparmor.d
   /usr/bin/dumb-init (19826) cri-containerd.apparmor.d
   /nginx-ingress-controller (19838) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19864) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19869) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19870) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19871) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19872) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19873) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19874) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19875) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19876) cri-containerd.apparmor.d
   /usr/local/nginx/sbin/nginx (19877) cri-containerd.apparmor.d
   /usr/bin/kube-controllers (56874) cri-containerd.apparmor.d
   /usr/local/bin/kube-scheduler (62513) cri-containerd.apparmor.d
   /usr/local/bin/etcd (64804) cri-containerd.apparmor.d

或者使用 ps 添加 -Z 标志,以显示每个进程的安全配置文件。




最后修改 2023.12.05: docs: udpate apparmor (8cd2b40)