一、最小特权原则(POLP)
1)最小特权原则 (Principle of least privilege,POLP) :
是一种信息安全概念,即为用户提供执行其工作职责所需的最 小权限等级或许可。 最小特权原则被广泛认为是网络安全的最佳实践,也是保护高价值数据和资产的特权访问的基本方式。
2)最小特权原则 (POLP) 重要性:
- 减少网络攻击面:当今,大多数高级攻击都依赖于利用特权凭证。通过限制超级用户和管理员权限,最小权限执行有 助于减少总体网络攻击面。
- 阻止恶意软件的传播: 通过在服务器或者在应用系统上执行最小权限,恶意软件攻击(例如SQL注入攻击)将很难 提权来增加访问权限并横向移动破坏其他软件、设备。
- 有助于简化合规性和审核:许多内部政策和法规要求都要求组织对特权帐户实施最小权限原则,以防止对关键业务系 统的恶意破坏。最小权限执行可以帮助组织证明对特权活动的完整审核跟踪的合规性。
3)在团队中实施最小特权原则 (POLP) :
- 在所有服务器、业务系统中,审核整个环境以查找特权帐户(例如SSH账号、管理后台账号、跳板机账号);
- 减少不必要的管理员权限,并确保所有用户和工具执行工作时所需的权限;
- 定期更改管理员账号密码;
- 监控管理员账号操作行为,告警通知异常活动。
二、AppArmor 限制容器对资源访问
AppArmor(Application Armor) 是一个 Linux 内核安全模块,可用于限制主机操作系统上运行的进程的功能。每个 进程都可以拥有自己的安全配置文件。安全配置文件用来允许或禁止特定功能,例如:网络访问、文件读/写/执行权限等。(类似SELinux)
AppArmor 对操作系统和应用程序所受到的威胁进行从内到外的保护,简单的说,AppArmor 是与 SELinux 类似的一个访问控制系统,通过它可以指定程序可以读、写或运行哪些文件,是否可以打开 网络端口等。作为对传统 Unix 的自主访问控制模块的补充,AppArmor 提供了强制访问控制机制,它 已经被整合到 2.6 版本的 Linux 内核中。目前 Ubuntu 自带了 Apparmor。
Linux发行版内置:Ubuntu、Debian
使用场景:AppArmor 可以配置为任何应用程序减少潜在的攻击面,并且提供更加深入的防御。 它通过调整配置文件进行配置,以允许特定程序或容器所需的访问, 如 Linux 权能字、网络访问、文件权限等。防止黑客在二进制目录下放如木马文件替换常用命令等。
2.1 Apparmor两种工作模式:
- Enforcement(强制模式) :在这种模式下,配置文件里列出的限制条件都会得到执行,并且对于违反这些限制条 件的程序会进行日志记录。(类似SELinux的enforcing)
- Complain(投诉模式):在这种模式下,配置文件里的限制条件不会得到执行,Apparmor只是对程序的行为进行 记录。一般用于调试。例如程序可以写一个在配置文件里注明只读的文件,但 Apparmor 不会对程序的行为进行限 制,只是进行记录。(类似SELinux的permissive)
常用命令:
参考:Ubuntu Manpage: apparmor_parser - loads AppArmor profiles into the kernel
- apparmor_status:查看AppArmor配置文件的当前状态的
- apparmor_parser:将AppArmor配置文件加载到内核中
- apparmor_parser <profile> # 加载到内核中
- apparmor_parser -r <profile> # 重新加载配置
- apparmor_parser -R <profile> # 删除配置
- aa-complain:将AppArmor配置文件设置为投诉模式,需要安装apparmor-utils软件包
- aa-enforce:将AppArmor配置文件设置为强制模式,需要安装apparmor-utils软件包
2.2 K8s使用AppArmor的先决条件:
K8s版本v1.4+,检查是否支持:kubectl describe node | grep AppArmor
- Linux内核已启用AppArmor,查看cat /sys/module/apparmor/parameters/enabled
- CRI 容器运行时 需要支持AppArmor,目前Docker已支持
示例:AppArmor 目前处于测试阶段,因此在注解中指定AppArmor策略配置文件。
apiVersion: v1
kind: Pod
metadata:
name: hello-apparmor
annotations:
container.apparmor.security.beta.kubernetes.io/<container_name>: localhost/<profile_ref>
...
- <container_name> # Pod中容器名称
- <profile_ref> # Pod所在宿主机上策略名,默认目录/etc/apparmor.d/
补充:AppArmor 基于Linux内核实现,需要在宿主机上执行加载操作,kubelet会读取加载的配置文件应用到容器中,执行相应的策略限制(包括容器文件、目录、网络等)
2.3 访问控制与资源限制
1)文件系统的访问控制
Apparmor 可以对某一个文件,或者某一个目录下的文件进行访问控制,包括以下几种访问模式:
字符 |
描述 |
r |
读 |
w |
写 |
a |
追加 |
k |
文件锁定 |
l |
链接 |
x |
可执行 |
匹配目录和文件:
通配符 |
描述 |
示例 |
* |
在目录级别匹配 零个或多个字符 |
/dir/* 匹配目录中的任何文件 /dir/a* 匹配目录中以a开头的任意文件 /dir/*.png 匹配目录中以.png结尾的任意文 件 /dir/a*/ 匹配/dir里面以a开头的目录 /dir/*a/ 匹配/dir里面以a结尾的目录 |
** |
在多个目录级别 匹配零个或多个 字符 |
/dir/** 匹配/dir目录或者/dir目录下任何文件 和目录 /dir/**/ 匹配/dir或者/dir下面任何目录 |
[]、[^] |
字符串,匹配其 中任意字符 |
/dir/[^.]* 匹配/dir目录中以.之外的任何文件 /dir/**[^/] 匹配/dir目录或者/dir下面的任何 目录中的任何文件 |
在配置文件中的写法,如:/tmp r, (表示可对/tmp 目录下的文件进行读取)
注意:没在配置文件中列出的文件,程序是不能访问
2)资源限制
Apparmor 可以提供类似系统调用 setrlimit 一样的方式来限制程序可以使用的资源。要限制资源, 可在配置文件中这样写:
set rlimit [resource] <= [value],
其 resource 代表某一种资源,value 代表某一个值,要对程序可以使用的虚拟内存做限制时,可以 这样写:
set rlimit as<=1M, (可以使用的虚拟内存最大为 1M)
3)访问网络
Apparmor 可以程序是否可以访问网络进行限制,在配置文件里的语法是:
network [ [domain] [type] [protocol] ]
要让程序可以进行所有的网络操作,只需在配置文件中写:
network,
要允许程序使用在 IPv4 下使用 TCP 协议,可以这样写:
network inet tcp,
使用Ubuntu搭建k8s环境下安装apparmor
apt-get install apparmor-utils apparmor-profiles apparmor-profiles-extra -y
注:Apparmor 的 profile 配置文件保存在目录/etc/apparmor.d,对应的日志3721
文件记录在 /var/log/messages
案例:限制容器对目录或者文件的访问
实施步骤:
1.将自定义策略配置文件保存到 /etc/apparmor.d/
2.加载配置文件到内核:apparmor_parser <profile>
3.创建Pod时,注解指定策略配置名
工作流程:
1)自定义策略配置文件
vi /etc/apparmor.d/k8s-deny-write
# include <tunables/global> //导入依赖
profile k8s-deny-write flags=(attach_disconnected) { //指定策略名
# include <abstractions/base>
file, # 允许所有文件读写
deny /bin/** w, # 拒绝所有文件写
deny /data/www/** w,
}
- 第一行:导入依赖,遵循C语言约定
- 第二行:指定策略名
- 第三行:{} 策略块
2)加载配置文件到内核
# 查看加载的配置文件
apparmor_parser status# 加载配置文件到内核
apparmor_parser k8s-deny-write
3)创建Pod并注解指定策略配置名YAML文件
apiVersion: v1
kind: Pod
metadata:
name: hello-apparmor
annotations:
container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-deny-write
spec:
nodeName: k8s-node1 # 由于策略是指定加载在宿主机,需要指定该宿主机节点
containers:
- name: hello
image: busybox
command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
注释:container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-deny-write
- hello 指定的【spec】字段中创建的容器名字;表示对这个容器进行实在策略的应用。
- localhost 表示指定本地的策略文件的策略名(注:是配置策略中的策略名,非文件名)
三、Seccomp 限制容器进程系统调用
对于 Linux 来说,用户层一切资源相关操作都需要通 过系统调用来完成;系统调用实现技术层次上解耦, 内核只关心系统调用API的实现,而不必关心谁调用的。
调用关系图:
Seccomp(Secure computing mode) 是一个 Linux 内核安全模块,可用于应用进程允许使用的系统调用。 容器实际上是宿主机上运行的一个进程,共享宿主机内核,如果所有容器都具有任何系统调用的能力,那么容器如果被 入侵,就很轻松绕过容器隔离更改宿主机系统权限或者进入宿主机。 使用Seccomp机制就可以限制容器系统调用,有效减少攻击面。
Linux发行版内置:CentOS、Ubuntu
K8s使用Seccomp的先决条件:
Seccomp在Kubernetes 1.3版本引入,在1.19版本成为GA版本,因此K8s中使用Seccomp可以通过以下两种方式:
- <profile> # Pod所在宿主机上策略文件名,默认目录:/var/lib/kubelet/seccomp
1)1.19版本之前
annotations:
seccomp.security.alpha.kubernetes.io/pod: "localhost/<profile>"
2)1.19版本+
apiVersion: v1
kind: Pod
metadata:
name: hello-seccomp
spec:
securityContext:
seccompProfile:
type: Localhost
localhostProfile: <profile> # Pod所在宿主机上策略文件名,默认目录:/var/lib/kubelet/seccomp
containers:
...
seccomp 基本配置文件包括三个元素:
- defaultAction:在 syscalls部分未定义的任何 系统调用默认动作为允许
- SCMP_ACT_ALLOW 允许
- syscalls
- names 系统调用名称,可以换行写多个
- SCMP_ACT_ERRNO 阻止系统调用
示例:禁止容器使用chmod
1)自定义seccomp策略配置文件:
注意:Pod所在宿主机上配置策略文件,默认目录/var/lib/kubelet/seccomp(没有该目录则自己创建)
[root@k8s-node1-1-72 ~]# mkdir /var/lib/kubelet/seccomp
[root@k8s-node1-1-72 ~]# vi /var/lib/kubelet/seccomp/chmod.json
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": [
"chmod"
],
"action": "SCMP_ACT_ERRNO"
}
]
}
2)创建Pod并注解指定策略配置名YAML文件
[root@k8s-master-1-71 ~]# kubectl apply -f test-seccomp.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-seccomp
spec:
nodeName: k8s-node1-1-72 # 由于策略是指定加载在宿主机,需要指定该宿主机节点
securityContext:
seccompProfile:
type: Localhost
localhostProfile: chmod.json # 指定Pod所在宿主机上策略文件名
containers:
- image: busybox
name: bs
command:
- sleep
- 24h
测试:在Pod中授予 /etc/hosts 执行权限
[root@k8s-master-1-71 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-seccomp 1/1 Running 0 5s
[root@k8s-master-1-71 ~]# kubectl exec -it hello-seccomp -- sh
/ # chmod +x /etc/hosts
chmod: /etc/hosts: Operation not permitted
示例:禁止容器使用mkdir
注意:编辑策略文件后,需要重启Pod才生效
vi /var/lib/kubelet/seccomp/chmod.json
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": [
"chmod",
"mkdir" # 注意:增加系统调用需要添加【,】
],
"action": "SCMP_ACT_ERRNO"
}
]
}
# 需要重启Pod,加载生效
[root@k8s-master-1-71 ~]# kubectl delete -f test-seccomp.yaml
[root@k8s-master-1-71 ~]# kubectl apply -f test-seccomp.yaml
[root@k8s-master-1-71 ~]# kubectl exec -it hello-seccomp -- sh
/ # mkdir /data
mkdir: can't create directory '/data': Operation not permitted
补充:大多数容器运行时都提供一组允许或不允许的默认系统调用。通过使用 runtime/default 注释 或将 Pod 或容器的安全上下文中的 seccomp 类型设置为 RuntimeDefault,可以轻松地在 Kubernetes 中应用默认值。
Docker默认配置说明:Seccomp security profiles for Docker | Docker Docs
课后作业
1、在工作节点上加载课堂上讲解的apparmor策略文件k8s-deny-write,并在 Pod中应用该策略
2、在工作节点上加载课堂上讲解的seccomp文件,禁止容器里使用chmod命令, 并在Pod中应用该策略
小结
本篇为 【Kubernetes CKS认证 DAY3】的开篇学习笔记,希望这篇笔记可以让您初步了解到 最小特权原则(POLP)、AppArmor 限制容器对资源访问,不妨跟着我的笔记步伐亲自实践一下吧!
Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。