• 在kubernetes里使用AppArmor限制容器对资源的访问


    一.系统环境

    本文主要基于Kubernetes1.22.2和Linux操作系统Ubuntu 18.04。

    服务器版本 docker软件版本 Kubernetes(k8s)集群版本 kube-bench版本 CPU架构
    Ubuntu 18.04.5 LTS Docker version 20.10.14 v1.22.2 0.6.7 x86_64

    Kubernetes集群架构:k8scludes1作为master节点,k8scludes2,k8scludes3作为worker节点。

    服务器 操作系统版本 CPU架构 进程 功能描述
    k8scludes1/192.168.110.128 Ubuntu 18.04.5 LTS x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master节点
    k8scludes2/192.168.110.129 Ubuntu 18.04.5 LTS x86_64 docker,kubelet,kube-proxy,calico k8s worker节点
    k8scludes3/192.168.110.130 Ubuntu 18.04.5 LTS x86_64 docker,kubelet,kube-proxy,calico k8s worker节点

    二.前言

    在现代的云计算环境中,安全是每个开发者和运维人员必须关注的问题。尤其是在运行容器的环境中,如何确保容器之间以及容器与宿主机之间的安全隔离,防止恶意行为对系统造成破坏,是一个非常重要的课题。本文将介绍如何使用 AppArmor 来限制容器对资源的访问,提高系统的安全性。

    使用 AppArmor 来限制容器对资源的访问的前提是已经有一套可以正常运行的Kubernetes集群,关于Kubernetes(k8s)集群的安装部署,可以查看博客《Ubuntu 安装部署Kubernetes(k8s)集群》https://www.cnblogs.com/renshengdezheli/p/17632858.html。

    三.AppArmor简介

    AppArmor 是一种 Linux 内核模块,用于提供强制访问控制(MAC)功能。它允许管理员为每个进程定义详细的访问控制策略,从而限制进程对文件、目录、网络接口等资源的访问。通过使用 AppArmor,我们可以有效地防止恶意软件或错误配置的应用程序对系统资源造成不必要的影响。

    AppArmor 的规则文件通常位于 /etc/apparmor.d/ 目录下。每个规则文件对应一个应用或服务,文件名通常以路径开头,后面跟着应用的名称。例如,对于 Nginx 服务器,其规则文件名为 /etc/apparmor.d/usr.sbin.nginx

    AppArmor 规则由一系列的匹配语句组成,每条语句表示一个访问控制规则。规则的基本结构如下:

    <profile> <options> <match> <permissions> <files> <paths> <commands> </profile>
    

    其中:

    • :指定规则所属的 profile,可以是预定义的 profile(如 usr.sbin.nginx),也可以是自定义的 profile。
    • :可选字段,用于指定 profile 的行为选项,如是否启用日志记录等。
    • :必选字段,用于指定规则适用的条件,如进程名称、用户等。
    • :必选字段,用于指定允许或拒绝的操作类型,如读、写、执行等。
    • :可选字段,用于指定规则适用的文件类型,如普通文件、目录、设备文件等。
    • :可选字段,用于指定规则适用的文件路径模式。
    • :可选字段,用于指定规则适用的命令名称。

    四.AppArmor和SELinux的区别

    虽然 AppArmor 和 SELinux 都是 Linux 上的访问控制工具,但它们之间存在一些区别:

    • 设计理念:AppArmor 的设计目标是简单易用,而 SELinux 则更注重细粒度的控制。因此,AppArmor 的策略配置文件通常比 SELinux 更简洁。
    • 配置方式:AppArmor 的策略配置文件采用一种类似于 DSL(领域特定语言)的语法,易于阅读和编写;而 SELinux 的策略配置文件则采用一种更复杂的布尔表达式语法。
    • 社区支持:由于 AppArmor 的配置相对简单,因此在社区中得到了更广泛的支持和应用。

    五.使用AppArmor限制nginx程序访问目录

    5.1 安装nginx

    创建目录存放文件。

    root@k8scludes1:~# mkdir systemsafe   
    
    root@k8scludes1:~# cd systemsafe/
    

    安装nginx。

    root@k8scludes1:~/systemsafe# apt-get install nginx
    
    root@k8scludes1:~/systemsafe# which nginx
    /usr/sbin/nginx
    

    nginx安装好之后就可以访问nginx了。

    root@k8scludes1:~/systemsafe# curl 192.168.110.128
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    ......
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    

    5.2 修改nginx的默认主页

    创建一个safe目录和一个unsafe目录。

    root@k8scludes1:~/systemsafe# mkdir -p /data/www/safe /data/www/unsafe
    

    在safe目录写入index.html。

    root@k8scludes1:~/systemsafe# vim /data/www/safe/index.html
    
    root@k8scludes1:~/systemsafe# cat /data/www/safe/index.html
    <html> 
            <b>Hello! Accessing this file is allowed.b> 
    html>
    

    在unsafe目录写入index.html。

    root@k8scludes1:~/systemsafe# vim /data/www/unsafe/index.html
    
    root@k8scludes1:~/systemsafe# cat /data/www/unsafe/index.html
    <html> 
            <b>Hello! Accessing this file is forbidden.b> 
    html>
    

    修改nginx配置文件,修改nginx的默认主页目录为/data/www。

    root@k8scludes1:~/systemsafe# vim /etc/nginx/nginx.conf 
    
    root@k8scludes1:~/systemsafe# grep -A10 sites-enabled /etc/nginx/nginx.conf
            #include /etc/nginx/sites-enabled/*;
    
            server {
              listen 8080;
              location / {
                  #root /data/www; 改变nginx的默认主页
                  root /data/www;
                }
            }
    }
    

    重启nginx。

    root@k8scludes1:~/systemsafe# systemctl restart nginx
    

    访问nginx目录,现在safe和unsafe都可以访问。

    root@k8scludes1:~/systemsafe# curl 192.168.110.128:8080/safe/
    <html> 
            <b>Hello! Accessing this file is allowed.</b> 
    </html>
    
    root@k8scludes1:~/systemsafe# curl 192.168.110.128:8080/unsafe/
    <html> 
            <b>Hello! Accessing this file is forbidden.</b> 
    </html>
    

    我们需要配置AppArmor,使nginx可以访问/data/www/safe/目录,不可以访问/data/www/unsafe/目录,保护敏感数据。

    5.3 安装AppArmor实用工具

    查看系统有没有安装AppArmor。

    root@k8scludes1:~/systemsafe# dpkg -l | grep apparmor
    ii  apparmor                               2.12-4ubuntu5.1                                 amd64        user-space parser utility for AppArmor
    ii  libapparmor1:amd64                     2.12-4ubuntu5.1                                 amd64        changehat AppArmor library
    

    更新软件源。

    root@k8scludes1:~/systemsafe# apt-get update
    

    安装apparmor-utils ,apparmor-profiles, apparmor-profiles-extra。

    apparmor-utils 是一组用户空间的命令行实用工具,可以帮助我们很好的管理 AppArmor 。

    apparmor-profiles, apparmor-profiles-extra是一些预先配置的配置文件,这些配置文件一般来说是比较完善的,但是也需要根据实际需要进行修改。

    root@k8scludes1:~# apt-get install apparmor-utils apparmor-profiles apparmor-profiles-extra -y
    

    查看apparmor软件包,现在apparmor工具包就安装好了。

    root@k8scludes1:~# cd systemsafe/
    
    root@k8scludes1:~/systemsafe# dpkg -l | grep apparmor
    ii  apparmor                               2.12-4ubuntu5.1                                 amd64        user-space parser utility for AppArmor
    ii  apparmor-profiles                      2.12-4ubuntu5.1                                 all          experimental profiles for AppArmor security policies
    ii  apparmor-profiles-extra                1.19                                            all          Extra profiles for AppArmor Security policies
    ii  apparmor-utils                         2.12-4ubuntu5.1                                 amd64        utilities for controlling AppArmor
    ii  libapparmor1:amd64                     2.12-4ubuntu5.1                                 amd64        changehat AppArmor library
    ii  python3-apparmor                       2.12-4ubuntu5.1                                 amd64        AppArmor Python3 utility library
    ii  python3-libapparmor                    2.12-4ubuntu5.1                                 amd64        AppArmor library Python3 bindings
    

    查看apparmor是否开启。

    root@k8scludes1:~/systemsafe# aa-enabled 
    Yes
    

    apparmor的配置文件在/etc/apparmor.d目录下。

    root@k8scludes1:~/systemsafe# cd /etc/apparmor.d/
    
    root@k8scludes1:/etc/apparmor.d# pwd
    /etc/apparmor.d
    

    usr.bin.man表示 /usr/bin/man的man程序。

    root@k8scludes1:/etc/apparmor.d# ls
    abstractions        local           tunables                  usr.bin.totem-previewers      usr.lib.dovecot.dovecot-lda        usr.lib.dovecot.pop3             usr.sbin.dovecot   usr.sbin.smbldap-useradd
    apache2.d           lxc             usr.bin.chromium-browser  usr.lib.dovecot.anvil         usr.lib.dovecot.imap               usr.lib.dovecot.pop3-login       usr.sbin.identd    usr.sbin.tcpdump
    bin.ping            lxc-containers  usr.bin.irssi             usr.lib.dovecot.auth          usr.lib.dovecot.imap-login         usr.lib.dovecot.ssl-params       usr.sbin.mdnsd     usr.sbin.traceroute
    cache               sbin.dhclient   usr.bin.lxc-start         usr.lib.dovecot.config        usr.lib.dovecot.lmtp               usr.lib.snapd.snap-confine.real  usr.sbin.nmbd
    disable             sbin.klogd      usr.bin.man               usr.lib.dovecot.deliver       usr.lib.dovecot.log                usr.sbin.apt-cacher-ng           usr.sbin.nscd
    force-complain      sbin.syslogd    usr.bin.pidgin            usr.lib.dovecot.dict          usr.lib.dovecot.managesieve        usr.sbin.avahi-daemon            usr.sbin.rsyslogd
    gst_plugin_scanner  sbin.syslog-ng  usr.bin.totem             usr.lib.dovecot.dovecot-auth  usr.lib.dovecot.managesieve-login  usr.sbin.dnsmasq                 usr.sbin.smbd
    

    5.4 AppArmor规则解释

    aa-autodep生成nginx进程的apparmor配置文件,aa-autodep nginx自动给nginx生成一套规则。

    root@k8scludes1:/etc/apparmor.d# aa-autodep nginx
    Writing updated profile for /usr/sbin/nginx.
    
    root@k8scludes1:/etc/apparmor.d# pwd
    /etc/apparmor.d
    
    root@k8scludes1:/etc/apparmor.d# ls usr.sbin.nginx 
    usr.sbin.nginx
    

    查看自动生成的规则文件。

    apparmor涉及两种模式,每个配置文件都可以在强制(enforcing)模式(阻止访问不允许的资源)或投诉(complain)模式 (仅报告冲突)下运行:

    1. complain模式(即使没有满足条件也放行) ;
    2. enforce模式(必须满足条件)。

    /usr/sbin/nginx flags=(complain)表示启用的是complain模式。

    root@k8scludes1:/etc/apparmor.d# vim usr.sbin.nginx
    
    root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx
    # Last Modified: Thu May 12 16:12:18 2022
    #include 
    
    /usr/sbin/nginx flags=(complain) {
      #include 
    
      /lib/x86_64-linux-gnu/ld-*.so mr,
      /usr/sbin/nginx mr,
    
    }
    
    

    把usr.sbin.nginx的模式变为enforce模式。

    root@k8scludes1:/etc/apparmor.d# aa-enforce nginx
    Setting /usr/sbin/nginx to enforce mode.
    

    现在usr.sbin.nginx就是enforce模式。

    root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx
    # Last Modified: Thu May 12 16:12:18 2022
    #include 
    
    /usr/sbin/nginx {
      #include 
    
      /lib/x86_64-linux-gnu/ld-*.so mr,
      /usr/sbin/nginx mr,
    
    }
    

    查看apparmor权限帮助。

    root@k8scludes1:/etc/apparmor.d# man 5 apparmor.d 
    

    AppArmor允许规则说明:

    • allow /path/file (允许访问/path/file文件) ,allow /path/file 规则也可以写为/path/file ,因为默认是allow规则;
    • allow /path/* (允许访问/path/目录下所有文件,不支持递归) ;
    • allow /path/** (允许访问/path/目录下所有文件,支持递归),对于/path/aa/aa1/aaa1目录,allow /path/*规则能匹配到/path/aa 不能匹配到/path/aa/aa1和/path/aa/aa1/aaa1 ,allow /path/** 规则能匹配 /path/目录下所有文件。

    AppArmor拒绝规则说明:

    • deny /path/file
    • deny /path/*
    • deny /path/**

    AppArmor权限说明:

    • r: 读;
    • w: 写;
    • m: 存储器映射;
    • k: 文件锁定;
    • l: 创建硬链接;
    • ix: 执行并继承该安全配置;
    • Px: 在清理环境之后,执行并使用其他安全配置;
    • Ux: 在清理环境之后,执行不做限制。

    apparmor常用命令:

    • aa-unconfined:用于检测运行在系统上监听网络连接且不受AppArmor保护的应用程序;
    • aa-autodep:用于创建配置文件的基本框架,该模板投入使用前需要完善。生成的配置文件被加载时进入complain模式,报告应用程序中(尚未)被AppArmor规则覆盖的行为。
    • aa-genprof:生成一个基本配置文件。通过执行应用程序会激发一系列事件并记录在日志中,在配置策略时要认真考虑其中存在的问题,进一步细化配置文件。生成并被加载时会进入enforce模式。
    • aa-logprof:当应用程序已生成配置文件并处于complain模式时,其可交互式地扫描和检查由应用程序生成的日志条目,辅助完善配置策略。
    • aa-complain:将AppArmor配置文件从enforce切换为complain模式。不符合配置文件策略的行为会被记录,但不会被拒绝。
    • aa-enforce:将AppArmor配置文件的模式从complain切换到enforce。不符合配置文件策略的行为会被记录,且会被拒绝。

    5.5 配置AppArmor规则限制nginx程序访问目录

    编写AppArmor规则,deny /data/www/unsafe/** r 表示禁止读/data/www/unsafe/目录下的文件。

    root@k8scludes1:/etc/apparmor.d# vim usr.sbin.nginx 
    
    root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx
    # Last Modified: Thu May 12 16:12:18 2022
    #include 
    
    /usr/sbin/nginx {
      #include 
      
      deny /data/www/unsafe/** r,
      /lib/x86_64-linux-gnu/ld-*.so mr,
      /usr/sbin/nginx mr,
    
    }
    

    aa-complain nginx将usr.sbin.nginx切换为complain模式。

    root@k8scludes1:/etc/apparmor.d# aa-complain nginx
    Setting /usr/sbin/nginx to complain mode.
    

    aa-logprof:当应用程序已生成配置文件并处于complain模式时,其可交互式地扫描和检查由应用程序生成的日志条目,辅助完善配置策略。

    root@k8scludes1:/etc/apparmor.d# aa-logprof 
    Reading log entries from /var/log/syslog.
    Updating AppArmor profiles in /etc/apparmor.d.
    Complain-mode changes:
    
    Profile:    /usr/sbin/nginx
    Capability: dac_override
    Severity:   9
    
     [1 - #include ]
      2 - #include  
      3 - capability dac_override, 
    (A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish
    Adding #include  to profile.
    Deleted 5 previous matching profile entries.
    Enforce-mode changes:
    
    = Changed Local Profiles =
    
    The following local profiles were changed. Would you like to save them?
    
     [1 - /usr/sbin/nginx]
    (S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
    
    = Changed Local Profiles =
    
    The following local profiles were changed. Would you like to save them?
    
     [1 - /usr/sbin/nginx]
    (S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
    Writing updated profile for /usr/sbin/nginx.
    

    查看新的apparmor规则,拒绝访问/data/www/unsafe/**目录。

    • #include :这一行包含了一个内核参数,tunables/global 提供了对内核参数的访问,这些参数可以影响AppArmor如何加载和处理规则。
    • /usr/sbin/nginx flags=(complain) {:这行定义了规则集的应用范围。这里是针对位于 /usr/sbin/nginx 的程序(即Nginx服务器)应用这些规则。flags=(complain) 表示这些规则是以complain 模式(complain mode)运行,即AppArmor会记录不允许的操作,但不会阻止它们。
    • #include :包含基础抽象规则,这些规则提供了最基本的安全策略,比如禁止写文件系统等。
    • #include :包含LXC容器基础抽象规则,这些规则适用于容器环境,提供了与容器相关的安全策略。
    • deny /data/www/unsafe/** r,:这一行表示禁止对 /data/www/unsafe/ 目录及其所有子目录进行读取操作。r 代表读取操作。这意味着Nginx不能访问这个目录或其子目录中的任何文件。这通常用于限制对敏感数据的访问。
    #include  表示加载默认的规则库
    root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx 
    # Last Modified: Fri May 13 11:37:31 2022
    #include 
    
    /usr/sbin/nginx flags=(complain) {
      #include 
      #include 
    
      deny /data/www/unsafe/** r,
    
    }
    

    现在访问nginx,safe目录能访问,unsafe目录访问不了。

    root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/safe/
    <html> 
            <b>Hello! Accessing this file is allowed.</b> 
    </html>
    
    
    root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/unsafe/
    <html>
    <head><title>403 Forbidden</title></head>
    <body bgcolor="white">
    <center><h1>403 Forbidden</h1></center>
    <hr><center>nginx/1.14.0 (Ubuntu)</center>
    </body>
    </html>
    

    切换为enforce模式。

    root@k8scludes1:/etc/apparmor.d# aa-enforce nginx
    Setting /usr/sbin/nginx to enforce mode.
    
    root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx 
    # Last Modified: Fri May 13 11:37:31 2022
    #include 
    
    /usr/sbin/nginx {
      #include 
      #include 
    
      deny /data/www/unsafe/** r,
    
    }
    

    enforce模式下,safe可以访问,unsafe访问不了,满足需求了

    root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/safe/
    <html> 
            <b>Hello! Accessing this file is allowed.</b> 
    </html>
    
    root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/unsafe/
    <html>
    <head><title>403 Forbidden</title></head>
    <body bgcolor="white">
    <center><h1>403 Forbidden</h1></center>
    <hr><center>nginx/1.14.0 (Ubuntu)</center>
    </body>
    </html>
    

    现在修改apparmor规则,使safe不能访问,unsafe能访问。

    root@k8scludes1:/etc/apparmor.d# vim usr.sbin.nginx 
    
    root@k8scludes1:/etc/apparmor.d# cat usr.sbin.nginx 
    # Last Modified: Fri May 13 11:37:31 2022
    #include 
    
    /usr/sbin/nginx {
      #include 
      #include 
    
      deny /data/www/safe/** r,
    
    }
    

    重新加载apparmor规则,使配置文件生效。

    root@k8scludes1:/etc/apparmor.d# /etc/init.d/apparmor reload
    [ ok ] Reloading apparmor configuration (via systemctl): apparmor.service.
    

    重新加载apparmor规则之后,safe不能访问,unsafe能访问。

    root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/unsafe/
    <html> 
            <b>Hello! Accessing this file is forbidden.</b> 
    </html>
    
    root@k8scludes1:/etc/apparmor.d# curl 192.168.110.128:8080/safe/
    <html>
    <head><title>403 Forbidden</title></head>
    <body bgcolor="white">
    <center><h1>403 Forbidden</h1></center>
    <hr><center>nginx/1.14.0 (Ubuntu)</center>
    </body>
    </html>
    

    六.在kubernetes里使用AppArmor限制容器对资源的访问

    6.1 检查环境

    在 Kubernetes v1.4 版本中才添加了对 AppArmor 的支持。验证节点的 Kubelet 版本。

    root@k8scludes1:~# kubectl get nodes -o=jsonpath={range .items[*]}{@.metadata.name}: {@.status.nodeInfo.kubeletVersion}\n{end}' 
    
    k8scludes1: v1.22.2 
    
    k8scludes2: v1.22.2 
    
    k8scludes3: v1.22.2 
    

    查看AppArmor 内核模块是否启用 。

    root@k8scludes1:/etc/apparmor.d# cat /sys/module/apparmor/parameters/enabled 
    Y 
    

    现在还没有pod。

    root@k8scludes1:/etc/apparmor.d# cd 
    
    root@k8scludes1:~# cd systemsafe/ 
    
    root@k8scludes1:~/systemsafe# kubectl get pod 
    No resources found in systemsafe namespace. 
    

    查看node节点的标签。

    root@k8scludes1:~/systemsafe# kubectl get nodes --show-labels
    NAME         STATUS   ROLES                  AGE   VERSION   LABELS
    k8scludes1   Ready    control-plane,master   30d   v1.22.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8scludes1,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
    k8scludes2   Ready    <none>                 30d   v1.22.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8scludes2,kubernetes.io/os=linux
    k8scludes3   Ready    <none>                 30d   v1.22.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8scludes3,kubernetes.io/os=linux
    

    给k8scludes3节点设置一个标签yy=xx。

    root@k8scludes1:~/systemsafe# kubectl label nodes k8scludes3 yy=xx  
    

    查看标签为yy=xx的节点,等下创建的pod,我们让其运行在k8scludes3节点。

    root@k8scludes1:~/systemsafe# kubectl get node -l yy=xx
    NAME         STATUS   ROLES    AGE   VERSION
    k8scludes3   Ready    <none>   30d   v1.22.2
    

    6.2 配置AppArmor规则

    先在k8scludes3节点设置apparmor规则。

    root@k8scludes3:~# cd /etc/apparmor.d/ 
    
    root@k8scludes3:/etc/apparmor.d# ls 
    abstractions  cache  disable  force-complain  local  lxc  lxc-containers  
    sbin.dhclient  tunables  usr.bin.lxc-start  usr.bin.man  usr.lib.snapd.snap-confine.real 
    usr.sbin.rsyslogd  usr.sbin.tcpdump 
    

    查看AppArmor 内核模块是否启用

    root@k8scludes3:~# cat /sys/module/apparmor/parameters/enabled 
    Y 
    

    创建一个k8s的apparmor规则文件。

    注意:拒绝的优先级高于允许的优先级 。

    apparmor的规则为 deny /tmp/aa/** rw 禁止在/tmp/aa/目录下读写 。

    k8s-apparmor-profile-deny-write是AppArmor规则的名字。

    root@k8scludes3:/etc/apparmor.d# vim k8s-apparmorprofile 
    
    root@k8scludes3:/etc/apparmor.d# cat k8s-apparmorprofile 
    #include  
    profile k8s-apparmor-profile-deny-write flags=(attach_disconnected) { 
    #include  
    #include  
    #file, 
    allow /proc/** rw, 
    allow /usr/bin/sleep rwkix, 
    allow /bin/* rwkix, 
    allow /root/** rw, 
    allow /etc/bash.bashrc rw, 
    allow /usr/bin/* rwkix, 
    allow /** rw, 
    deny /tmp/aa/** rw, 
    # Deny all file writes. 
    #deny /** w, 
    } 
    

    apparmor_status查看apparmor启用了哪些规则 。

    root@k8scludes3:/etc/apparmor.d# apparmor_status 
    apparmor module is loaded. 
    16 profiles are loaded. 
    16 profiles are in enforce mode. 
    /sbin/dhclient 
    /usr/bin/lxc-start 
    /usr/bin/man 
    /usr/lib/NetworkManager/nm-dhcp-client.action 
    /usr/lib/NetworkManager/nm-dhcp-helper 
    /usr/lib/connman/scripts/dhclient-script 
    /usr/lib/snapd/snap-confine 
    /usr/lib/snapd/snap-confine//mount-namespace-capture-helper 
    /usr/sbin/tcpdump 
    docker-default 
    lxc-container-default 
    lxc-container-default-cgns 
    lxc-container-default-with-mounting 
    lxc-container-default-with-nesting 
    man_filter 
    man_groff 
    0 profiles are in complain mode. 
    23 processes have profiles defined. 
    23 processes are in enforce mode. 
    docker-default (2298) 
    docker-default (2505) 
    docker-default (3726) 
    docker-default (3757) 
    docker-default (3782) 
    docker-default (4338) 
    docker-default (4419) 
    docker-default (4585) 
    docker-default (4615) 
    docker-default (4688) 
    docker-default (5109) 
    docker-default (5173) 
    docker-default (5295) 
    docker-default (5362) 
    docker-default (5490) 
    docker-default (5642) 
    docker-default (5651) 
    docker-default (5726) 
    docker-default (5946) 
    docker-default (5999) 
    docker-default (6023) 
    docker-default (6894) 
    docker-default (7234) 
    0 processes are in complain mode. 
    0 processes are unconfined but have a profile defined. 
    

    我们创建的规则还没有启用 ,apparmor启用的规则里没有k8s-apparmor-profile-deny-write规则 。

    root@k8scludes3:/etc/apparmor.d# apparmor_status | grep k8s-apparmor-profile-deny-write 
    

    加载规则 。

    root@k8scludes3:/etc/apparmor.d# apparmor_parser -q k8s-apparmorprofile 
    

    现在k8s-apparmor-profile-deny-write规则就启用了 。

    root@k8scludes3:/etc/apparmor.d# apparmor_status | grep k8s-apparmor-profile-deny-write 
    k8s-apparmor-profile-deny-write 
    

    如果想要删除规则 ,apparmor_parser -R 删除规则 ,apparmor_parser -r 是替换规则 。

    root@k8scludes3:/etc/apparmor.d# apparmor_parser -R k8s-apparmorprofile 
    
    root@k8scludes3:/etc/apparmor.d# apparmor_status | grep k8s-apparmor-profile-deny-write 
    

    重新加载规则。

    root@k8scludes3:/etc/apparmor.d# apparmor_parser -q k8s-apparmorprofile 
    
    root@k8scludes3:/etc/apparmor.d# apparmor_status | grep k8s-apparmor-profile-deny-write 
    k8s-apparmor-profile-deny-write 
    

    6.3 使用AppArmor限制容器对资源的访问

    k8scludes3节点启用了apparmor规则之后,需要在k8scludes3节点创建pod ,回到k8scludes1节点,创建pod配置文件。

    nodeSelector:yy: xx 指定pod在k8scludes3上运行 ,command: ["sh","-c","sleep 100000"] 指定运行sleep进程 。

    root@k8scludes1:~/systemsafe# vim pod.yaml 
    
    root@k8scludes1:~/systemsafe# cat pod.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: null
      labels:
        run: podtest
      name: podtest
    spec:
      nodeSelector:
        yy: xx
      #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
      terminationGracePeriodSeconds: 0
      containers:
      - image: hub.c.163.com/library/centos:latest
        command: ["sh","-c","sleep 100000"]
        #imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像
        imagePullPolicy: IfNotPresent
        name: podtest
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
    status: {}
    

    创建pod。

    root@k8scludes1:~/systemsafe# kubectl apply -f pod.yaml 
    pod/podtest created 
    

    现在pod运行在k8scludes3节点,pod正常运行,不过我们没有在pod里启用apparmor规则 。

    root@k8scludes1:~/systemsafe# kubectl get pod -o wide 
    NAME     READY  STATUS   RESTARTS  AGE  IP           NODE       NOMINATED NODE READINESS GATES 
    podtest  1/1    Running  0        8s    10.244.1.121 k8scludes3 <none> <none> 
    

    删除pod。

    root@k8scludes1:~/systemsafe# kubectl delete pod podtest 
    pod "podtest" deleted 
    
    root@k8scludes1:~/systemsafe# kubectl get pod 
    No resources found in systemsafe namespace. 
    

    在pod里启用apparmor规则,添加的注解语法为:annotations:container.apparmor.security.beta.kubernetes.io/容器名字: localhost/apparmor规则名 。

    container.apparmor.security.beta.kubernetes.io/podtest: localhost/k8s-apparmor-profile-deny-write里,容器名为podtest,规则名为:k8s-apparmor-profile-deny-write。

    root@k8scludes1:~/systemsafe# vim pod.yaml 
    
    root@k8scludes1:~/systemsafe# cat pod.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: null
      labels:
        run: podtest
      name: podtest
      annotations:
        # Tell Kubernetes to apply the AppArmor profile "k8s-apparmor-example-deny-write".
        # Note that this is ignored if the Kubernetes node is not running version 1.4 or greater.
        container.apparmor.security.beta.kubernetes.io/podtest: localhost/k8s-apparmor-profile-deny-write
    spec:
      #nodeSelector:yy: xx 指定pod在k8scludes3上运行 
      nodeSelector:
        yy: xx
      #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。
      terminationGracePeriodSeconds: 0
      containers:
      - image: hub.c.163.com/library/centos:latest
        #command: ["sh","-c","sleep 100000"] 指定运行sleep进程
        command: ["sh","-c","sleep 100000"]
        #imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像
        imagePullPolicy: IfNotPresent
        name: podtest
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
    status: {}
    

    创建pod,pod正常运行。

    root@k8scludes1:~/systemsafe# kubectl apply -f pod.yaml 
    pod/podtest created 
    
    root@k8scludes1:~/systemsafe# kubectl get pod 
    NAME     READY STATUS   RESTARTS AGE 
    podtest  1/1   Running  0        5s 
    

    进入pod。

    root@k8scludes1:~/systemsafe# kubectl exec -it podtest -- bash 
    
    root@podtest:/# ls /tmp 
    
    root@podtest:/# mkdir /tmp/aa /tmp/bb/ 
    
    #apparmor的规则为 deny /tmp/aa/** rw 禁止在/tmp/aa/目录下读写,满足条件 
    root@podtest:/# touch /tmp/aa/aa1.txt 
    touch: cannot touch '/tmp/aa/aa1.txt': Permission denied 
    
    root@podtest:/# touch /tmp/bb/bb1.txt 
    
    root@podtest:/# ls /tmp/aa 
    
    root@podtest:/# ls /tmp/bb 
    bb1.txt 
    
    #退出pod
    root@podtest:/# exit 
    exit 
    

    删除pod。

    root@k8scludes1:~/systemsafe# kubectl delete pod podtest 
    pod "podtest" deleted   
    

    七.总结

    通过使用 AppArmor,我们可以在不牺牲性能的前提下,为容器提供有效的安全隔离。Kubernetes 的集成使得配置和管理 AppArmor 规则变得更加便捷。通过精确的规则设置,我们可以确保容器只能访问它所需要的资源,从而降低系统的风险暴露。

  • 相关阅读:
    router基础使用
    ARMv8平台上安装QT开发环境
    在线社交网络分析 github,在线社交网络分析软件
    狂砸40亿美元,亚马逊向OpenAI竞争对手Anthropic投资
    windows11 安装cnpm 报错 Error: EPERM: operation not permitted 没权限
    SpringMVC的请求处理流程及核心组件
    koa-session获取不到session踩坑记录
    FTX的前世今生:崛起、辉煌与崩塌
    固定代码移动到0000:0200
    在网络层怎样防御入侵行为?
  • 原文地址:https://www.cnblogs.com/renshengdezheli/p/18220674