前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >介绍一个小工具:Security Profiles Operator

介绍一个小工具:Security Profiles Operator

作者头像
崔秀龙
发布2022-03-31 20:01:49
6150
发布2022-03-31 20:01:49
举报
文章被收录于专栏:伪架构师伪架构师伪架构师

在云原生安全方面,Kubernetes 在不同维度提供了很多的不同内容,例如 RBAC、Networkpolicy、SecurityContext 等等,种种措施中,像我这样基础不牢的 YAML 工程师最头大的可能就要数 SecurityContext 里面的 SELinux、Seccomp 和 AppArmor 三大块了。Security Profiles Operator 项目为此而来,希望能够降低在 Kubernetes 集群中使用这些安全技术的难度。在项目网页上转了转,发现他所说的简化,除了定义几个 CRD 封装这样的 Operator 传统技能之外;还有一个使用 CRD 在节点间传输 Security Profile 的能力;最后也是最重要的,提供了很方便的录制功能,这倒是真的戳中了痛点——手写 Profile 固然酷炫,录制生成才是生产力啊。目前支持的功能矩阵如下:

功能

Seccomp

SELinux

AppArmor

Profile CRD

Yes

Yes

Yes

ProfileBinding

Yes

No

No

Deploy profiles into nodes

Yes

Yes

WIP

Remove profiles no longer in use

Yes

Yes

WIP

Profile Auto-generation (logs)

Yes

WIP

No

Profile Auto-generation (ebpf)

Yes

No

No

Audit log enrichment

Yes

WIP

Yes

部署

如果目标环境不是 Openshift,首先需要安装 Cert Manager

$ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.6.1/cert-manager.yaml

customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
...

接下来安装 SPO:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/security-profiles-operator/master/deploy/operator.yaml
customresourcedefinition.apiextensions.k8s.io/profilebindings.security-profiles-operator.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/profilerecordings.security-profiles-operator.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/seccompprofiles.security-profiles-operator.x-k8s.io created

查看生成的 CRD,大致功能如下

全名

缩写

命名空间级

功能

AppArmorProfile

aa

true

用于保存 AppArmor Profile

ProfileBinding

N/A

true

把 Profile 绑定到 Pod 上

ProfileRecording

N/A

true

用录制的方式生成 Profile

RawSelinuxProfile

N/A

true

SeccompProfile

sp

true

用于保存 Seccomp Profile

SecurityProfileNodeStatus

spns

true

SecurityProfilesOperatorDaemon

spod

true

SelinuxProfile

N/A

true

用于保存 Selinux Profile

最后创建一个命名空间 spo,并以此作为缺省命名空间,进行后续的试用过程。

借助 SPO 传递 Seccomp

创建一个 Seccomp Profile,其中加入了对系统调用的审计日志:

apiVersion: security-profiles-operator.x-k8s.io/v1beta1
kind: SeccompProfile
metadata:
  namespace: spo
  name: seccomp-profile-sample
spec:
  defaultAction: SCMP_ACT_LOG

Apply 之后 kubectl get sp seccomp-profile-sample -o yaml ,会发现状态如下:

metadata:
...
  finalizers:
  - gke-gcp-vlab-k8s-default-pool-7c61250b-x3h1-delete
  - gke-gcp-vlab-k8s-default-pool-7c61250b-n9l3-delete
  - gke-gcp-vlab-k8s-default-pool-7c61250b-86wz-delete
...
status:
...
  localhostProfile: operator/spo/seccomp-profile-sample.json
  status: Installed

表明 Profile 已经部署到三个节点,状态为 Installed

这样一来就可以创建一个 Pod,引用这个 Profile:

apiVersion: v1
kind: Pod
metadata:
  name: sleep-pod
spec:
  securityContext:
    seccompProfile:
      type: Localhost
      localhostProfile: operator/spo/seccomp-profile-sample.json
  containers:
    - name: sleep
      image: dustise/sleep:v0.9.6
      volumeMounts:
      - name: kubelet
        mountPath: /data/kubelet
  volumes:
  - name: kubelet
    hostPath:
        path: /var/lib/kubelet/seccomp/operator/spo
        type: Directory

Pod 创建之后,进入 Pod Shell,可以看到我们生成的 Profile:

$ kubectl exec -it sleep-pod -- bash
bash-5.0# cd /data/kubelet
bash-5.0# ls
seccomp-profile-sample.json
bash-5.0# cat seccomp-profile-sample.json
{"defaultAction":"SCMP_ACT_LOG"}

接下来执行一下 CURL 点什么,登录节点看看日志

$ sudo journalctl -xe  | grep -i seccomp | grep curl
Mar 21 10:12:44 gke-gcp-vlab-k8s-default-pool-d97cb436-mdgb audit[180209]: SECCOMP auid=4294967295 uid=0 gid=0 ses=4294967295 subj==docker-default (enforce) pi
d=180209 comm="curl" exe="/usr/bin/curl" sig=0 arch=c000003e syscall=231 compat=0 ip=0x7f6d3b8d76f9 code=0x7ffc0000

删掉 Pod。便于进行后续步骤

如果我不想修改 Pod,可以用 ProfileBinding 把 Seccomp Profile 和镜像绑定到一起,如下配置:

apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
kind: ProfileBinding
metadata:
  name: sample-binding
spec:
  profileRef:
    kind: SeccompProfile
    name: seccomp-profile-sample
  image: dustise/sleep:v0.9.6

看看重建一个没有 securityPod 的 Pod 会有什么变化:

apiVersion: v1
kind: Pod
metadata:
  name: sleep-pod
spec:
  containers:
    - name: sleep
      image: dustise/sleep:v0.9.6
      volumeMounts:
      - name: kubelet
        mountPath: /data/kubelet
  volumes:
  - name: kubelet
    hostPath:
        path: /var/lib/kubelet/seccomp/operator/spo
        type: Directory

创建之后,我们看看线上的 YAML:

$ kubectl get po sleep-pod -o yaml
apiVersion: v1
kind: Pod
...
    securityContext:
      seccompProfile:
        localhostProfile: operator/spo/seccomp-profile-sample.json
        type: Localhost

果然这里被修改了。有兴趣还可以查查,这里用到的 Mutating Webhook。

录制 Profile

SPO 支持三种录制模式,分别是 hooklogeBPF

hook 指的是 OCI hooks,但是目前 containerd 还不支持。

log 则是使用基于日志的录制方式。

eBPF 自然就是最新的基于 eBPF 的录制了。

缺省情况下 spod 没有开启 eBPF 录制功能,需要把开关 spec.enableBpfRecorder 设置为 true

$ kubectl patch spod spod -n security-profiles-operator  --type=merge -p '{"spec":{"enableBpfRecorder":true}}'
securityprofilesoperatordaemon.security-profiles-operator.x-k8s.io/spod patched

接下来创建一个录制对象:

apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
kind: ProfileRecording
metadata:
  name: sample-recording
spec:
  kind: SeccompProfile
  recorder: bpf
  podSelector:
    matchLabels:
      app: sleep

提交之后,我们给上一个 Pod 加上标签 app=sleep,创建出来,然后随便执行点什么:

$ kubectl apply -f recording.yaml
profilerecording.security-profiles-operator.x-k8s.io/sample-recording created
$ kubectl apply -f plain-pod.yaml
pod/sleep-pod created
$ kubectl exec -it sleep-pod -- curl http://jd.com
...
$ kubectl exec -it sleep-pod -- mkdir 123
...
$ kubectl exec -it sleep-pod -- ping baidu.com
...

删除 Pod,查看 SeccompProfile:

$ kubectl delete -f plain-pod.yaml
pod "sleep-pod" deleted
$ kubectl get sp
NAME                     STATUS      AGE
sample-recording-sleep   Installed   9s

$ kubectl get sp sample-recording-sleep -o yaml

kind: SeccompProfile
metadata:
  creationTimestamp: "2022-03-21T14:07:23Z"
  finalizers:
  - gke-gcp-vlab-k8s-default-pool-d97cb436-5tct-delete
  - gke-gcp-vlab-k8s-default-pool-d97cb436-mdgb-delete
  - gke-gcp-vlab-k8s-default-pool-d97cb436-d8d1-delete
  generation: 1
  labels:
    spo.x-k8s.io/profile-id: SeccompProfile-sample-recording-sleep
...
spec:
  architectures:
  - SCMP_ARCH_X86_64
  defaultAction: SCMP_ACT_ERRNO
  syscalls:
  - action: SCMP_ACT_ALLOW
    names:
    - arch_prctl
    - bind
...

这里看到,删除 Pod 之后,录制过程自动生成了新的 SeccompProfile,其中包含了 Pod 工作过程中使用的配置,并且已经被安装到了各个节点之上。

牢骚和尾声

Kubernetes 普及之后,新方向层出不穷,正如杨蒙恩说的——“遍地是大王,短暂又辉煌”,不过安全可能是目前确定性最高的一块内容,决不短暂。所谓安全无小事,没有网格、没有 Serverless 甚至没有多集群、经济性、混布都可以,没有安全可能就全盘皆输了;也不要总想着新瓶装旧酒,挑挑节点、固定一下 IP 就完事了,BMW 装上马鞍之后,丢的不只是风阻和车顶,至少车友群是不太容易混了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 伪架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 部署
  • 借助 SPO 传递 Seccomp
  • 录制 Profile
  • 牢骚和尾声
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档