跳到主要内容

K8s容器运行环境安全加固

K8s容器运行环境安全加固

image-20230528102956392

目录

[toc]

1、最小特权原则(POLP)

**最小特权原则 (Principle of least privilege,POLP) :**是一种信息安全概念,即为用户提供执行其工作职责所需的最小权限等级或许可。

最小特权原则被广泛认为是网络安全的最佳实践,也是保护高价值数据和资产的特权访问的基本方式。

最小特权原则 (POLP) 重要性:

• **减少网络攻击面:**当今,大多数高级攻击都依赖于利用特权凭证。通过限制超级用户和管理员权限,最小权限执行有助于减少总体网络攻击面。

阻止恶意软件的传播: 通过在服务器或者在应用系统上执行最小权限,恶意软件攻击(例如SQL注入攻击)将很难提权来增加访问权限并横向移动破坏其他软件、设备。

有助于简化合规性和审核:许多内部政策和法规要求都要求组织对特权帐户实施最小权限原则,以防止对关键业务系统的恶意破坏。最小权限执行可以帮助组织证明对特权活动的完整审核跟踪的合规性。

在团队中实施最小特权原则 (POLP) :

• 在所有服务器、业务系统中,审核整个环境以查找特权帐户(例如SSH账号、管理后台账号、跳板机账号);

• 减少不必要的管理员权限,并确保所有用户和工具执行工作时所需的权限;

• 定期更改管理员账号密码;

• 监控管理员账号操作行为,告警通知异常活动。

2、AppArmor限制容器对资源访问

AppArmor(Application Armor) 是一个 Linux 内核安全模块,可用于限制主机操作系统上运行的进程的功能。每个进程都可以拥有自己的安全配置文件。安全配置文件用来允许或禁止特定功能,例如网络访问、文件读/写/执行权限等。

Linux发行版内置:Ubuntu、Debian centos里默认没有内置AppArmor。与其同功能的程序centos里是selinux(但是selinux使用起来相对比较复杂,因此工作环境里一般都是关闭状态的)

Apparmor两种工作模式:

• Enforcement(强制模式) :在这种模式下,配置文件里列出的限制条件都会得到执行,并且对于违反这些限制条件的程序会进行日志记录。

• Complain(投诉模式):在这种模式下,配置文件里的限制条件不会得到执行,Apparmor只是对程序的行为进行记录。一般用于调试。

常用命令:

• 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软件包

K8s使用AppArmor的先决条件:

• K8s版本v1.4+,检查是否支持:kubectl describe node |grep AppArmor

• Linux内核已启用AppArmor,查看 cat /sys/module/apparmor/parameters/enabled

• 容器运行时需要支持AppArmor,目前Docker已支持

image-20230527074341706

image-20230527074412195

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

image-20230527074834938

==💘 案例:容器文件系统访问限制-2023.5.28(测试成功)==

步骤:

1、将自定义策略配置文件保存到/etc/apparmor.d/

2、加载配置文件到内核:apparmor_parser

3、Pod注解指定策略配置名

本次测试为ubuntu k8s环境,这里只做文档记录。

image-20230527075100044

  • 创建pod

image-20230527075228892

image-20230527075255959

  • 默认情况,在容器里是可以随意创建文件的

image-20230527075342825

  • 限制容器某个目录/文件的目的

黑客攻击场景,限制容器进程对其它特定目录/文件的写入

  • 创建策略文件

image-20230527080041960

image-20230527080200129

相当于一个黑名单,黑名单之外的都可以。

usr/bin等目录。

  • 将策略文件加载到内核中(注意:这里在是node1上配置的

image-20230527080705657

image-20230527080734017

  • Pod注解指定策略配置名

image-20230527080822987

image-20230527080852401

image-20230527080914366

是宿主机的能力,宿主机对容器上的进程做访问控制,因为容器是宿主机上的一个进程。

  • 部署

image-20230527081149521

  • 验证

image-20230527081218351

image-20230527081335639

image-20230527081356813

image-20230527081424997

符合预期。

生产用的并不多,有一定复杂性,不用过多去研究它。

image-20230527081553317

3、Seccomp 限制容器进程系统调用

image-20230527082024539

Seccomp(Secure computing mode) 是一个 Linux 内核安全模块,可用于应用进程允许使用的系统调用。

容器实际上是宿主机上运行的一个进程,共享宿主机内核,如果所有容器都具有任何系统调用的能力,那么容器如果被入侵,就很轻松绕过容器隔离更改宿主机系统权限或者进入宿主机。这就可以使用Seccomp机制限制容器系统调用,有效减少攻击面。

Linux发行版内置:CentOS、Ubuntu

附件:《Linux:系统调用列表.pdf》 文档存放位置:

D:\BaiduSyncdisk\1、IT\5、Other\附件资源\Linux:系统调用列表.pdf

image-20230529063735424

image-20230529063753020

==💘 案例:Seccomp 限制容器进程系统调用-2023.5.28(测试成功)==

image-20230527082841422

GA:毕业

image-20230527083157011

  • 实战步骤
graph LR
A[实战步骤] -->B(1.随意查看一个容器)
A[实战步骤] -->C(2.宿主机上创建配置文件)
A[实战步骤] -->D(3.创建pod)
A[实战步骤] -->E(4.测试)
  • 实验环境
实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
k8s version:v1.20.0
docker://20.10.7
  • 实验软件
链接:https://pan.baidu.com/s/12Gq4QoK3_iSbBOZslhhZJg?pwd=0820 
提取码:0820
2023.5.28-seccomp-code

image-20230528104110266

1.随意查看一个容器

[root@k8s-master1 ~]#kubectl get po
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 10 6d10h
……
[root@k8s-master1 ~]#kubectl exec -it busybox -- sh
/ #
/ # chmod 777 /etc/hosts

默认,在容器里是可以执行chmod命令的。

接下来,我们将使用Seccomp 限制容器进程系统调用,阻止chmod命令的运行。

image-20230528072043935

有些命令对应的系统调用方法和命令名同名,但有些是不同的,这些需要注意下。

2.宿主机上创建配置文件

本次,我们在k8s-node2节点上配置策略文件。

[root@k8s-node2 ~]#mkdir /var/lib/kubelet/seccomp
[root@k8s-node2 ~]#vi /var/lib/kubelet/seccomp/chmod.json
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": [
"chmod"
],
"action": "SCMP_ACT_ERRNO"
}
]
}

3.创建pod

[root@k8s-master1 ~]#mkdir seccomp
[root@k8s-master1 ~]#cd seccomp/
apiVersion: v1
kind: Pod
metadata:
name: hello-seccomp
spec:
nodeName: "k8s-node2"
securityContext:
seccompProfile:
type: Localhost
localhostProfile: chmod.json
containers:
- image: nginx
name: web

#部署:
[root@k8s-master1 seccomp]#kubectl apply -f pod.yaml
pod/hello-seccomp created

4.测试

[root@k8s-master1 seccomp]#kubectl get po
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 10 6d10h
busybox2 1/1 Running 10 6d10h
hello-seccomp 1/1 Running 0 23s
py-k8s 1/1 Running 2 4d
web520 1/1 Running 0 2d23h
[root@k8s-master1 seccomp]#kubectl exec -it hello-seccomp -- bash
root@hello-seccomp:/# chmod 777 /etc/hosts
root@hello-seccomp:/#

哎,好奇怪,这个chmod命令依然还可以在这个容器里运行。

我们再换个busybox镜像再测试下:

[root@k8s-master1 seccomp]#cp  pod.yaml pod2.yaml
[root@k8s-master1 seccomp]#vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-seccomp2
spec:
nodeName: "k8s-node2"
securityContext:
seccompProfile:
type: Localhost
localhostProfile: chmod.json
containers:
- image: busybox
name: busybox
command:
- sleep
- 24h

#部署:
[root@k8s-master1 seccomp]#kubectl apply -f pod2.yaml
pod/hello-seccomp2 created

#测试:
[root@k8s-master1 seccomp]#kubectl get po
NAME READY STATUS RESTARTS AGE
hello-seccomp 1/1 Running 0 4m26s
hello-seccomp2 1/1 Running 0 4s
[root@k8s-master1 seccomp]#kubectl exec -it hello-seccomp2 -- sh
/ #
/ # chmod 777 /etc/hosts
chmod: /etc/hosts: Operation not permitted
/ #

哇哦,这里使用busybox镜像测试,就符合预期效果了,但是前面的那个nginx镜像对chmod系统调用没有效果。

这里我们再增加下一条系统调用规则(阻止mkdir命令的使用)

#修改sccomp策略文件:
[root@k8s-node2 ~]#vi /var/lib/kubelet/seccomp/chmod.json
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": [
"chmod",
"mkdir"
],
"action": "SCMP_ACT_ERRNO"
}
]
}

#创建新的测试pod
#这个需要重新创建pod才能生效:
#而AppArmor是修改就能生效,是加载到内核里的。
[root@k8s-master1 seccomp]#cp pod.yaml pod3.yaml
[root@k8s-master1 seccomp]#cp pod2.yaml pod4.yaml
[root@k8s-master1 seccomp]#vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-seccomp3
spec:
nodeName: "k8s-node2"
securityContext:
seccompProfile:
type: Localhost
localhostProfile: chmod.json
containers:
- image: nginx
name: web

[root@k8s-master1 seccomp]#vim pod4.yaml
apiVersion: v1
kind: Pod
metadata:
name: hello-seccomp4
spec:
nodeName: "k8s-node2"
securityContext:
seccompProfile:
type: Localhost
localhostProfile: chmod.json
containers:
- image: busybox
name: busybox
command:
- sleep
- 24h

#部署:
[root@k8s-master1 seccomp]#kubectl apply -f pod3.yaml
pod/hello-seccomp3 created
[root@k8s-master1 seccomp]#kubectl apply -f pod4.yaml
pod/hello-seccomp4 created

#测试:
[root@k8s-master1 seccomp]#kubectl get po
NAME READY STATUS RESTARTS AGE
……
hello-seccomp3 0/1 Error 2 25s
hello-seccomp4 1/1 Running 0 22s
[root@k8s-master1 seccomp]#kubectl logs hello-seccomp3
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/05/27 23:40:25 [emerg] 1#1: mkdir() "/var/cache/nginx/client_temp" failed (1: Operation not permitted)
nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (1: Operation not permitted)

[root@k8s-master1 seccomp]#kubectl exec -it hello-seccomp4 -- sh
/ # chmod 777 /etc/hosts
chmod: /etc/hosts: Operation not permitted
/ # mkdir a
mkdir: can't create directory 'a': Operation not permitted
/ #

可以看到,nginx镜像的pod无法启动,报nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (1: Operation not permitted)错误。

说明禁用mkdir命令成功了,同样busybox镜像也是可以禁用成功的。

至于,chmod命令nginx镜像没能实现效果,可能和镜像有关吧(或者系统调用的名称不同)。

[root@k8s-master1 seccomp]#kubectl exec -it hello-seccomp -- bash  #(nginx镜像)
root@hello-seccomp:/# cat /etc/issue
Debian GNU/Linux 11 \n \l

测试结束。😘

关于我

我的博客主旨:

  • 排版美观,语言精炼;
  • 文档即手册,步骤明细,拒绝埋坑,提供源码;
  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码 x2675263825 (舍得), qq:2675263825。

image-20230107215114763

🍀 微信公众号 《云原生架构师实战》

image-20230107215126971

🍀 语雀

https://www.yuque.com/xyy-onlyone

image-20230515221819681

🍀 csdn https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

image-20230107215149885

🍀 知乎 https://www.zhihu.com/people/foryouone

image-20230107215203185

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!