# 官方提供@yunTaoScripts 系统设置 Apparmor 🔥🔥
从操作系统层面,提升系统安全性。 容器也是共享宿主机内核。
- 物理机增加一个模块,pod和物理机同时总数加 1。
root@vms33:~# lsmod | wc -l
125
root@vms33:~# kubectl exec -it centos -- lsmod | wc -l
125
root@vms33:~# modprobe pcspkr
root@vms33:~# kubectl exec -it centos -- lsmod | wc -l
126
root@vms33:~# lsmod | wc -l
126
- 重启禁用以下两个模块
root@vms33:/etc/modprobe.d# cat xx.conf
blacklist kvm
blacklist kvm_intel
- 临时删除模块
root@vms33:/etc/modprobe.d# modprobe -r kvm_intel
root@vms33:/etc/modprobe.d# kubectl exec -it centos -- lsmod | wc -l
123
root@vms33:/etc/modprobe.d# lsmod | wc -l
123
POLP 最小授权原则 (Principal of least privilege)
- 启动模块一定要少
- 授权按需最小授权
- 权限分离,各司其职
# 非集群环境部署apparmor
类似selinux,centos 没有apparmor。设置进程可以访问哪些文件,不可以访问哪些文件。系统工具。
# 创建nginx应用
apt install nginx
mkdir -p /data/www/allow /data/www/deny
cp /var/www/html/index.nginx-debian.html /data/www/allow/index.html
cp /var/www/html/index.nginx-debian.html /data/www/deny/index.html
vim /data/www/allow/index.html
vim /data/www/deny/index.html
cd /etc/nginx/conf.d/
vim host.conf
nginx -s reload
nginx -s reload
root@vms150:/etc/nginx/conf.d# cat host.conf
server {
listen 8080 default_server;
root /data/www;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
# 标准配置的文件
root@vms150:/etc/nginx/conf.d# ll /etc/apparmor.d/
-rw-r--r-- 1 root root 125 Nov 23 2018 usr.bin.lxc-start
-rw-r--r-- 1 root root 2857 Apr 7 2018 usr.bin.man
-rw-r--r-- 1 root root 26245 Jul 10 2020 usr.lib.snapd.snap-confine.real
-rw-r--r-- 1 root root 1550 Apr 24 2018 usr.sbin.rsyslogd ##定义能访问到的文件
-rw-r--r-- 1 root root 1353 Apr 1 2018 usr.sbin.tcpdump
- 安装apparmor工具包,会多出一些规则,但是还没有nginx
root@vms150:/etc/nginx/conf.d# apt install apparmor-profiles apparmor-utils -y
- 新增nginx规则
root@vms150:/etc/nginx/conf.d# aa-autodep nginx
Writing updated profile for /usr/sbin/nginx.
root@vms150:/etc/nginx/conf.d# ls /etc/apparmor.d/
sbin.dhclient usr.lib.dovecot.config usr.lib.dovecot.managesieve-login usr.sbin.nginx
- 标准配置文件
root@vms150:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Tue Sep 6 11:09:42 2022
#include <tunables/global>
/usr/sbin/nginx flags=(complain) { ##标志位
#include <abstractions/base>
/lib/x86_64-linux-gnu/ld-*.so mr,
/usr/sbin/nginx mr, ##可读
}
root@vms150:/etc/apparmor.d# apparmor_parser -r usr.sbin.nginx #检查配置文件是否合规
标志位
- 模式标志
- enforce #不写flags=(complain) 代表强制模式
- complain
- 相对标志
- chroot_relative
- namespace_relative
- 附加标志 2个值,各选一个
- attch_disconnected
- no_attch_disconnected 或者
- chroot_attach
- chroot_no_attach
- 开启apparmor 强制模式后,nginx访问失败,进程重启失败。 开启后无权限访问nginx日志文件和配置文件
root@vms150:/etc/apparmor.d# aa-enforce nginx
Setting /usr/sbin/nginx to enforce mode.
root@vms150:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Tue Sep 6 11:09:42 2022
#include <tunables/global>
/usr/sbin/nginx {
#include <abstractions/base>
/lib/x86_64-linux-gnu/ld-*.so mr,
/usr/sbin/nginx mr,
}
- 查看apparmor 限制,并解除限制
root@vms150:/etc/apparmor.d# aa-logprof
Reading log entries from /var/log/syslog.
Updating AppArmor profiles in /etc/apparmor.d.
Enforce-mode changes:
Profile: /usr/sbin/nginx
Capability: dac_override
Severity: 9
[1 - #include <abstractions/lxc/container-base>]
2 - #include <abstractions/lxc/start-container>
3 - capability dac_override,
(A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish
Adding #include <abstractions/lxc/container-base> to profile.
Deleted 2 previous matching profile entries.
= 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.
root@vms150:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Tue Sep 6 11:35:33 2022
#include <tunables/global>
/usr/sbin/nginx {
#include <abstractions/base>
#include <abstractions/lxc/container-base>
}
- 拒绝deny访问
root@vms150:/etc/apparmor.d# cat usr.sbin.nginx
# Last Modified: Tue Sep 6 11:35:33 2022
#include <tunables/global>
/usr/sbin/nginx {
#include <abstractions/base>
#include <abstractions/lxc/container-base>
allow /data/www/allow/* r,
/data/www/allow/* r, # 不写allow 或者 deny,默认allow
deny /data/www/deny/* r, ## 同时写allow 和 deny, 默认deny
}
root@vms150:/etc/apparmor.d# apparmor_parser -r usr.sbin.nginx
root@vms150:/etc/apparmor.d# nginx -s reload
# 集群下部署Apparmor
在k8s 集群下, 我们是 要对pod 的访问做限制,pod中运行什么进程我们也不知道,所以不适合用标准的配置文件。通过未关联的配置可以限制pod里的所有进程。
# 未关联的配置文件
- 查看apparmor启用规则
root@vms34:~# 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
cri-containerd.apparmor.d
lxc-container-default
lxc-container-default-cgns
lxc-container-default-with-mounting
lxc-container-default-with-nesting
- 创建配置并加载profile
root@vms34:/etc/apparmor.d# cat > aa.conf
#include <tunables/global>
profile profile1 {
#include <abstractions/base>
}
root@vms34:/etc/apparmor.d# apparmor_parser -q aa.conf ## 加载配置 文件 不发出警告
root@vms34:/etc/apparmor.d# apparmor_status | grep profile1
profile1
apparmor_parser 用法
root@vms34:/etc/apparmor.d# apparmor_parser -h
-r, --replace Replace apparmor definitions
-R, --remove Remove apparmor definitions
# 创建pod并引用apparmor规则
root@vms33:~# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod2
name: pod2
annotations:
container.apparmor.security.beta.kubernetes.io/pod2: localhost/profile1
# 👆🏻容器名称 👆🏻pod所在节点 👆🏻节点apparmor规则
spec:
nodeName: vms34.rhce.cc
terminationGracePeriodSeconds: 0
containers:
- image: centos
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 1d"]
name: pod2
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
root@vms33:~# kubectl apply -f pod2.yaml
pod/pod2 created
root@vms33:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod2 0/1 CrashLoopBackOff 1 (4s ago) 5s
root@vms33:~# kubectl logs pod2
sh: /usr/bin/sleep: Permission denied
- 增加apparmor 权限
root@vms34:~# cat /etc/apparmor.d/aa.conf
#include <tunables/global>
profile profile1 {
#include <abstractions/base>
allow /usr/bin/sleep rwix,
}
root@vms34:~# apparmor_parser -r /etc/apparmor.d/aa.conf
root@vms33:~# kubectl delete pod pod2
pod "pod2" deleted
root@vms33:~# kubectl apply -f pod2.yaml
pod/pod2 created
root@vms33:~# kubectl logs pod2
root@vms33:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod2 1/1 Running 0 11s
- 执行命令
root@vms33:~# kubectl exec -it pod2 -- bash
bash: /root/.bashrc: Permission denied
- 修改apparmor 规则 增加
allow /root/.bashrc r,
root@vms34:~# cat /etc/apparmor.d/aa.conf
#include <tunables/global>
profile profile1 {
#include <abstractions/base>
allow /usr/bin/sleep rwix,
allow /root/.bashrc r,
}
- 报错发生了变化
root@vms33:~# kubectl delete pod pod2
pod "pod2" deleted
root@vms33:~# kubectl apply -f pod2.yaml
pod/pod2 created
root@vms33:~# kubectl exec -it pod2 -- bash
bash: /etc/bashrc: Permission denied
- 修改apparmor 规则,增加
allow /etc/bashrc r,
root@vms34:~# cat /etc/apparmor.d/aa.conf
#include <tunables/global>
profile profile1 {
#include <abstractions/base>
allow /usr/bin/sleep rwix,
allow /root/.bashrc r,
allow /etc/bashrc r,
}
- 此时sh 正常,但是ls 不正常。这样下去要一个一个授权很麻烦。
root@vms33:~# kubectl apply -f pod2.yaml
root@vms33:~# kubectl exec -it pod2 -- sh
root@vms33:~# kubectl exec -it pod2 -- sh
sh: /usr/bin/ls: Permission denied
sh-4.#
- 增加
#include <abstractions/bash>
,就可以 使用exec了。
root@vms34:~# cat /etc/apparmor.d/aa.conf
#include <tunables/global>
profile profile1 {
#include <abstractions/base>
#include <abstractions/bash>
allow /usr/bin/sleep rwix,
allow /usr/bin/ls rwix,
}
- 此时 无法访问文件
root@vms33:~# kubectl exec -it pod2 -- bash
[I have no name!@pod2 /]# ls
ls: cannot open directory '.': Permission denied
- 增加
flags=(attach_disconnected)
,file
。 root@vms34:~# cat /etc/apparmor.d/aa.conf #include <tunables/global> profile profile1 flags=(attach_disconnected){ #include <abstractions/base> #include <abstractions/bash> allow /usr/bin/sleep rwix, allow /usr/bin/ls rwix, file, } - 访问正常
root@vms33:~# kubectl exec -it pod2 -- bash
[root@pod2 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
- 限制特定目录
#include <tunables/global>
profile profile1 flags=(attach_disconnected){
#include <abstractions/base>
#include <abstractions/bash>
allow /usr/bin/sleep rwix,
allow /usr/bin/ls rwix,
file,
deny /tmp/ r, ## 只限制 tmp 目录,不限制 子目录。
}
#include <tunables/global>
profile profile1 flags=(attach_disconnected){
#include <abstractions/base>
#include <abstractions/bash>
allow /usr/bin/sleep rwix,
allow /usr/bin/ls rwix,
file,
deny /tmp/* r, ## 只限制 tmp 目录下第一层子目录。
}
#include <tunables/global>
profile profile1 flags=(attach_disconnected){
#include <abstractions/base>
#include <abstractions/bash>
allow /usr/bin/sleep rwix,
allow /usr/bin/ls rwix,
file,
deny /tmp/** r, ## 限制 tmp 下所有子目录。
}
- 换一个nginx镜像,pod 又会起不来,增加这行配置
#include <abstractions/lxc/container-base>
root@vms34:~# cat /etc/apparmor.d/aa.conf
#include <tunables/global>
profile profile1 flags=(attach_disconnected){
#include <abstractions/base>
#include <abstractions/bash>
#include <abstractions/lxc/container-base> ### 增加这行配置
allow /usr/bin/sleep rwix,
allow /usr/bin/ls rwix,
file,
deny /tmp/ r,
}
← 快速链接