一.APPArmor
1.简介
AppArmor(Application Armor) 是一个 Linux 内核安全模块,用于限制主机操作系统上运行的进程。每个进程都可以拥有自己的安全配置文件,安全配置文件用来允许或禁止特定功能,例如网络访问、文件读/写/执行权限等。
是Linux发行版的内置功能,比如Ubuntu、Debian、SUSE,而CentOS和redhat系统没有这个AppArmor,其功能相当于selinux,但selinux安全程度不高,也不方便使用,所以一般人不用。
Ubuntu系统携带了许多没有合并到上游 Linux 内核中的 AppArmor 补丁, 包括添加附加钩子和特性的补丁。Kubernetes 只在上游版本中测试过,不承诺支持其他特性。
2.工作模式
Enforcement(强制模式) :在这种模式下,配置文件里列出的限制条件都会得到执行,并且对于违反这些限制条件的程序会进行日志记录,相当于selinux的enforcing模式。
Complain(投诉模式):在这种模式下,配置文件里的限制条件不会得到执行,Apparmor只是对程序的行为进行记录,一般用于调试,相当于selinux的permissive模式。
3.使用前提
K8s版本v1.4+,检查是否支持:kubectl describe node |grep AppArmor
Linux内核已启用AppArmor,查看 cat /sys/module/apparmor/parameters/enabled
容器运行时需要支持AppArmor,docker、CRI-O 、containerd都支持。
比如以下ubuntu系统核内核是支持的,但在centos系统是看不到apparmor进程的。
4.使用
4.1定义策略
vim /etc/apparmor.d/k8s-deny-write ##文件名称自定义。
#include <tunables/global> ##默认格式,导入依赖,遵循C语言约定。
profile k8s-deny-write flags=(attach_disconnected) { ##指定策略名,也就是命令能查到显示出来的策略名称。
#include <abstractions/base> ##定义策略。
file, ##允许所有文件读写。
deny /bin/** w, ##递归匹配,拒绝/目录下的所有目录和文件写权限。
}
profile k8s-deny-write flags=(attach_disconnected) {
file,
# Deny all file writes.
deny /** w,
}
通配符 | 描述 | 示例 |
---|---|---|
* | 在目录级别匹配零个或多个字符。 | /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下面的任何目录中的任何文件。 |
访问文件权限模式字符 | 描述 |
---|---|
r | 读 |
w | 写 |
a | 追加 |
k | 文件锁定 |
l | 链接 |
x | 可执行 |
4.2加载策略
apparmor_parser /etc/apparmor.d/k8s-deny-write
命令 | 解释 |
---|---|
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软件包。 |
4.3引用策略
定义pod.yaml时添加注解加以引用。
注意,引用的策略文件必须是要pod所在的宿主机上,实际生产中是需要运维来维护的,可以写脚本把策略文件给K8s集群每个节点分配上去并加载到内核。
apiVersion: v1
kind: Pod
metadata:
name: hello
annotations:
container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-deny-write
spec:
nodeName: master01
containers:
- name: hello
image: busybox
command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
#container.apparmor.security.beta.kubernetes.io/<container_name>: localhost/<profile_ref>
#< container_name >: Pod中容器名称。
#< profile_ref >: Pod所在宿主机上策略名,默认目录/etc/apparmor.d。
pod.yaml字段 | 解释 |
---|---|
<container_name> | pod.yaml文件里所针对的容器名称。 |
<profile_def> | Pod所在宿主机上策略名,引用刚刚定义的配置文件。 |
<profile_ref> | 可以是以下取值之一: runtime/default:应用运行时的默认配置。 localhost/<profile_name>:应用在主机上加载的名为 <profile_name> 的配置文件。 unconfined:表示不加载配置文件。 |
二.Seccomp
1.简介
Seccomp(Secure computing mode) 是一个 Linux 内核安全模块,可用于应用进程允许使用的系统调用。容器实际上是在宿主机上运行的一个进程,共享宿主机内核,如果所有容器都具有任何系统调用的能力,那么容器如果被入侵,就很轻松绕过容器隔离更改宿主机系统权限或者进入宿主机。这就可以使用Seccomp机制限制容器系统调用,有效减少攻击面。
Linux发行版内置:CentOS、Ubuntu。
2.type类型
pod.yaml中会定义Type字段,表示将应用哪种类型的seccomp配置文件,具有如下选项:
Localhost:应该使用在节点上的文件中定义的配置文件。
RuntimeDefault:应该使用容器运行时默认配置文件。
Unconfined:无限制,不使用策略。
3.案例
引用的策略文件必须是要pod所在的宿主机上,实际生产中是需要运维来维护的,可以写脚本把策略文件给K8s集群每个节点分配上去并加载到内核。
3.1创建默认文件路径
mkdir /var/lib/kubelet/seccomp
3.2生成限制策略
root@master01:/var/lib/kubelet/seccomp# vim k8s.json
{
"defaultAction": "SCMP_ACT_ALLOW", ##在syscalls部分未定义的任何系统调用默认动作为允许。
"syscalls": [
{
"names": [ ##系统调用名称,可以换行写多个。
"mkdir"
],
"action": "SCMP_ACT_ERRNO" ## 阻止自定义的系统调用。
}
]
}
3.3应用策略
apiVersion: v1
kind: Pod
metadata:
name: hello
spec:
nodeName: master01 ##需要执行该pod被分配的机器上是有限制策略的。
securityContext: ##添加此参数。
seccompProfile:
type: Localhost ##指定类型,调用本地自定义策略文件。
localhostProfile: k8s.json ##使用相对路径,指定应用策略名称。
containers:
- image: busybox
name: hello
command:
- sleep
- 24h
3.4进入容器并测试
/ # mkdir test
mkdir: can't create directory 'test': Operation not permitted
评论区