kube-bench测试准入
针对kubeadm创建的cluster运行CIS基准测试工具时,发现了多个必须解决的问题。
通过配置修复所有问题并重新启动受影响的组件以确保新设置生效。
修复针对kubelet发现的所有以下违规行为
Ensure that the anonymous-auth argument is set to false
Ensure that the -authorization-mode argument is not set to AlwaysAllow
尽可能使用Webhook 身份验证/授权
修复针对etcd发现的以下违规行为:
Ensure that the –client-cert-auth argument is set to true
分为几个部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
**1.修改kubelet配置文件/var/lib/kubelet/config.yaml** 修改为 anonymous: enabled: false webhook: cacheTTL: 0s enabled: true authorization: mode: Webhook **2.修改etcd配置文件/etc/kubernetes/manifests/etcd.yaml** 修改为 - --client-cert-auth=true **3.重启kubelet** systemctl daemon-reload systemctl restart kubelet 验证 kubectl get nodes |
使用TLS Secret
Context:
您需要使用存储在 TLS Secret 中的 SSL 文件来保护 Web 服务器的安全访问。
Task:
在 smart-rose 命名空间中为名为 smart-rose 的现有 Deployment 创建名为 smart-rose 的 TLS
Secret。
使用以下 SSL 文件:
证书:/home/candidate/ksmv00201-master/ca-cert/smart.web.k8s.crt
密钥:/home/candidate/ksmv00201-master/ca-cert/smart.web.k8s.key
Deployment 已配置为使用 TLS Secret。
请勿修改现有的 Deployment。
使用命令行创建Secret
1 2 3 |
kubectl -n smart-rose create secret tls smart-rose \ --cert=/home/candidate/ksmv00201-master/ca-cert/smart.web.k8s.crt \ --key=/home/candidate/ksmv00201-master/ca-cert/smart.web.k8s.key |
验证
1 2 |
kubectl get deployment -n smart-rose 看deploy是否正常 |
优化dockerfile和deployment
Task:
1、分析和编辑给定的 Dockerfile:/home/candidate/KSSC00301/Dockerfile(基于 ubuntu:16.04
镜像),并修改文件中可能涉及到的安全/最佳实践问题的一个异常。
2、分析和编辑给定的清单文件:/home/candidate/KSSC00301/deployment.yaml,并修改文件中有
安全/最佳实践问题的一个异常。
提示:
1、请勿添加或删除配置项,只需修改现有配置的属性值让以上两个配置都不在有安全/最佳实践问题。
2、如果需要非特权用户来执行任何项目,则请使用用户 ID 65535 的用户 nobody。
dockerfile优化
1 2 |
FROM ubuntu:16.04 USER **nobody** |
deployment优化
开启文件系统只读模式
关闭特权模式
1 2 3 4 5 6 7 8 9 10 |
... readOnlyRootFilesystem: true runAsUser: 65535 ... privileged: false ... 重新应用deployment文件 kubectl delete -f /home/candidate/KSSC00301/deployment.yaml kubectl apply -f /home/candidate/KSSC00301/deployment.yaml |
deployment安全管理securityContext
修改运行在namespace app名称空间里名为lamp-deployment的现有 Deployment,以便其容器:
·使用用户ID 30000运行
·使用只读的根文件系统
·禁止特权提升
您可以在/home/candidate/kssc00401/lamp-deployment.yaml中找到Deployment的清单文件。
添加securityContext配置
官网查找securityContext
找到Configure a Security Context for a Pod or Container
在containers的列表中给每个容器添加
1 2 3 4 5 6 |
securityContext: readOnlyRootFilesystem: true runAsUser: 30000 allowPrivilegeEscalation: false kubectl apply -f ... |
如果不是在容器级,而是在控制器级.spec设置也可以,但只能设置runAsUser,无法设置只读和特权
apiserver准入控制
Context:
出于测试目的,由 kubeadm 创建的 cluster 的 Kubernetes API 服务器临时配置为允许未经身份验证
和未经授权的访问。
Task:
重新配置cluster的kubernetes API服务,以确保只允许经过身份验证和授权的REST请求。具体要求如下:
1、 禁止匿名身份验证
2、 使用授权模式Node,RBAC
3、 使用准入控制器NodeRestriction
您可以使用集群位于
/etc/kubernetes/admin.conf 的原始 kubectl 配置文件来访问受保护的集群
最后删除anonymous的clusterRolebinding
修改/etc/kubernetes/manifests/kube-apiserver.yaml
1 2 3 |
--authorization-mode=Node,RBAC --enable-admission-plugins=NodeRestriction --anonymous-auth=false |
删除clusterRolebinding
1 2 3 4 |
kubectl get clusterRolebinding \ --kubeconfig=/etc/kubernetes/admin.conf | pgrep anonymous kubectl delete clusterRolebinding |
镜像安全扫描
Context:
cluster上设置了容器镜像扫描器,但尚未完全集成到cluster的配置中。您必须将容器镜像扫描完全集成到kubeadm配置的集群里。
Task:
在**/etc/kubernetes/controlconf目录中**,有不完整的配置,以及具有HTTPS 端点的
https://wakanda:8080/image_policy的功能性容器镜像扫描器:
首先,重新配置 API 服务器以启用所有准入控制插件,以支持提供的 AdmissionConfiguration 设置
接着,重新配置 ImagePolicyWebhook,确保在后端失效时拒绝不符合政策的镜像。
最后,为了验证配置的有效性,部署在/home/candidate/kssc00601/vulnerable-resource.yaml文件中
定义的测试资源,该资源使用一个应被拒绝的镜像。
您可以根据需要删除并重新创建该资源进行测试。
重启kubelet
解法
这个目录下有三个文件,分别是admissionConfig,KUBECONFIG,policy
只需要修改前两个
官网,找Admission Control in Kubernetes
修改admissionConfig文件
1 2 3 4 5 6 7 8 9 10 11 |
apiVersion: apiserver.config.k8s.io/v1 kind: AdmissionConfiguration plugins: - name: ImagePolicyWebhook configuration: imagePolicy: kubeConfigFile: <path-to-kubeconfig-file> allowTTL: 50 denyTTL: 50 retryBackoff: 500 defaultAllow: false |
修改KUBECONFIG
server: https://wakanda:8080/image_policy #改成题目给的webhook地址
修改apiserver配置文件
添加
1 2 |
--enable-admission-plugins=NodeRestriction,ImagePolicyWebhook --admission-control-config-file=/etc/kubernetes/controlconf/admission_configuration.yaml |
验证
通过应用题目给的/home/candidate/kssc00601/vulnerable-resource.yaml
如果直接报错镜像未验证,说明做成功了
Cilium网络策略
Task:
使用 Cilium 实现以下操作,以保护现有应用程序的内部和外部网络流量。
首先,在 nodecli 命名空间下创建一个名为 clium 的 L4 Cilium 网络策略,并根据以下要求进行配置:
1、允许 ingress-nginx-web 命名空间中的所有 Pod 访问 clium Deployment 中的 Pod。
2、要求相互身份验证来保障通信安全。
接下来,在前述网络策略的基础上,进行以下扩展:
1、允许主机访问 clium Deployment 中的 Pod。
2、禁用相互身份验证。
会给一个Cilium的官网https://cilium.io/
搜索Example,进入L4 Examples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: clium # 修改规则名称 namespace: nodecli # 选择对应ns spec: endpointSelector: matchLabels: app: clium # 选择带有 app=clium 标签的 Pod, clium-ddrgfa-avfdx ingress: - fromEndpoints: - matchLabels: kubernetes.io/metadata.name: ingress-nginx-web #允许来自ingress-nginx-web命名空间的 Pod authentication: #启动身份验证 mode: "required" - fromEntites: #允许主机访问clium pod - host |
修改docker服务权限
Task
执行以下任务,来保护kssc00801集群
从 docker 组中删除developer用户
注意: 不要从其他组中删除用户
重新配置并重启 Docker 守护进程,确保位于/var/run/docker.sock 的套接字文件由 root 组拥有。
重新配置并重启 Docker 守护进程,确保它不监听任何 TCP 协议的端口。
解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
删除用户 gpasswd -d developer docker 修改sock文件-用户 vim /usr/lib/systemd/system/docker.sock systemctl daemon-reload && systemctl restart docker # 不监听tcp协议 删除-H tcp://0.0.0.0:2375 修改docker的service文件-用户 vim /usr/lib/systemd/system/docker.service systemctl daemon-reload && systemctl restart docker |
升级k8s工作节点
Context:
当前使用 kubeadm 配置的集群最近完成了一次升级。由于兼容性原因,有一个节点被保留在较旧的版本上。
Task:
升级集群中的节点 node01,使其与control plane节点的版本保持一致。
正常是以官网为参考,本题是把node01从1.31.0升级到
1.31.1,如果是其他版本,
官网查找upgrading kubeadm cluster
1 2 3 4 5 6 7 8 9 |
查看当前版本,保证工作节点与控制节点版本一致 sudo apt-cache show kubeadm |grep xxx(版本) sudo apt-mark unhold kubelet && \ sudo apt-get update && sudo apt-get install -y kubelet='1.31.x-*' && \ sudo apt-mark hold kubelet sudo systemctl daemon-reload && systemctl restart kubelet |
使用ingress http代理
Task
在 prod01 namespace 创建一个名为 web 的 Ingress 资源,并根据以下要求配置:
1)将主机 web.k8singress.local 和所有路径的流量路由到现有的 web Service。
2)使用已存在的 web-cert Secret 进行 TLS 终止。
3)将所有 HTTP 请求重定向至 HTTPS。
提示:可使用以下命令测试 Ingress 配置:curl -Lk https://web.k8singress.local
官网查找ingress(有两个ingress)
搜tls
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
kubectl get ingressclasses # 查看ingressclass类名字和端口 nginx k8s.io/ingress-nginx <none> 22d 创建ingress.yaml,从官网复制过来 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web namespace: prod01 annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" spec: ingressClassName: nginx tls: - hosts: - web.k8singress.local secretName: web-cert rules: - host: web.k8singress.local http: paths: - path: / pathType: Prefix backend: service: name: web port: number: 80 kubectl apply -f ingress.yaml kubectl get ingress -n prod01 最后通过请求来进行访问 curl -Lk https://web.k8singress.local |
使用falco扫描识别异常行为pod
Task
属于应用程序 olla的一个 Pod 出现异常,正从敏感文件 /dev/mem 直接读取系统内存数据。
首先,识别出正在访问 /dev/mem 的异常 Pod
然后,将该异常 Pod 所属的 Deployment 缩减至零副本。
注意事项:
- 除缩小pod副本外,不修改 Deployment 的其他配置。
- 不对其他 Deployment 进行更改。
- 不要删除任何 Deployment。
考试的时候会给一个falco官网https://falco.org
搜索Basic Elements of Falco Rules
写falco配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
- list: mem_file items: [/dev/mem] - rule: devmem desc: cks condition: > fd.name in (mem_file) and evt.type in (open,write,read,mmap,ioctl) output: > Process ID: %proc.pid Command: %proc.cmdline File: %fd.name ID: %container.id priority: NOTICE logs: [file] 开始扫描 falco -M 30 -r /etc/falco/falco_rules-1.yaml >> devmem.log 扫描出来了之后,使用kubectl scale或kubectl edit调整deployment副本数为0 |
配置集群日志审计
您必须为 kubeadm 配置的集群启用审计。
Task
首先,请重新配置集群中的 APIserver 服务,以便:
1) /etc/kubernetes/logpolicy/sample-policy.yaml 提供了基本的策略,正在被使用
2)日志存储在 /var/log/kubernetes/audit-logs.txt 文件中
3)最多保留 3 个日志,保留时间为 5 天
注意:基本策略仅指定不记录的内容。
其次,编辑并扩展基本策略以记录:
1)RequestResponse 级别的 persistentvolumes 事件
2)front-apps namespace 中的 configmaps 事件的请求正文
3)Metadata 级别的所有 namespace 中的 ConfigMap 和 Secret 的更改
4)Metadata 级别记录所有其他请求
注意:确保 APIserver使用扩展后的策略。
解法:
官网搜索audit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
在/etc/kubernetes/logpolicy/sample-policy.yaml中 - level: RequestResponse resources: - group: "" # Resource "pods" doesn't match requests to any subresource of pods, # which is consistent with the RBAC policy. resources: ["persistentvolumes"] - level: Request resources: - group: "" # core API group resources: ["configmaps"] # This rule only applies to resources in the "kube-system" namespace. # The empty string "" can be used to select non-namespaced resources. namespaces: ["front-apps"] - level: Metadata resources: - group: "" # core API group resources: ["secrets", "configmaps"] omitStages: - "RequestReceived" 修改apiserver配置文件 /etc/kubernetes/ - --audit-policy-file=/etc/kubernetes/logpolicy/sample-policy.yaml #审计策略文件 - --audit-log-path=/var/log/kubernetes/audit-logs.txt #审计日志文件 - --audit-log-maxage=5 #保留5天 - --audit-log-maxbackup=3 #保留 3 个日志 重启kubelet 验证方式:查看audit的log tail -f /var/log/kubernetes/audit-logs.txt |
使用网络策略Networkpolicy
您需要通过 NetworkPolicy 来管理现有的 Deployments ,实现控制跨越不同namespace的流量。
Task
首先,在 prod namespace中创建一个名为 deny 的 NetworkPolicy,以阻止所有的入口流量。
其次,在 data 命名空间中创建一个名为 allow-from-prod 的 NetworkPolicy,以允许仅来自 prod
namespace 的 Pod 流量进入。使用 prod namespace的标签来允许流量。
提示:prod namespace标记 env: prod
data namespace标记 env: data
官方网站查找 Network Policies
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
--- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny namespace: prod spec: podSelector: {} policyTypes: - Ingress --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-prod namespace: data spec: podSelector: {} policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: env: prod |
SA异常
Context
在安全审计中发现,某个 Deployment 存在不符合安全要求的服务账号令牌,这可能会引发安全漏洞。
Task
首先,需要修改 monitor namespace 中现有的 stats-monitor-sa ServiceAccount,禁止自动挂载API 凭据。
接着,修改 monitor namespace 中现有的 stats-monitor Deployment,确保 ServiceAccount 令牌挂载到 /var/run/secrets/kubernetes.io/serviceaccount/token 路径。
通过名为 token 的投射卷注入该令牌。确保令牌以只读模式挂载
资源文件位置/home/candidate/stats-monitor/deployment1.yaml
官网搜索service account
寻找Configure service account for pods
就可以找到字段
1 2 |
automountServiceAccountToken:false 禁止自动挂载API凭据 |
添加只读挂载的字段
1 2 3 4 5 6 7 8 9 10 |
volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount/token name: token readOnly: true volumes: - name: token projected: sources: - serviceAccountToken: path: token |
基于bom创建SPDX文档
Task:
在 alpine namespace 中的 alpine Deployment 中,运行着三个不同版本的 Alpine 镜像容器。
首先,需要找出哪个 Alpine 镜像中包含了版本为 3.1.4-r5 的 libcrypto3 软件包。
其次,使用预安装的 bom 工具,在 /home/candidate/kssc00150/alpine.spdx 文件中为找出的镜像版本生成 SPDX 文档。
最后, 更新 alpine Deployment,删除使用上述找到镜像版本的容器。
Deployment 的清单文件可以在/home/candidate/kssc00150/alipine-deployment.yaml 中找到。
解法
通过kubectl exec -it -n alpine alpine-7949ddcc97-z9rqp -c alpine-container-2 -- apk list | grep libcrypto3
找到带有libcrypto3-3.1.4-r5的container
在deployment文件中将其删除,并更新
生成文档:
bom generate --image alpine:3.19.1 –output /home/candidate/kssc00150/alpine.spdx
pod安全标准
Context:
为满足要求,所有用户命名空间必须强制执行受限的 Pod 安全标准。
Task:
在 confidential namespace 命名空间中,有一个 Deployment 不符合限制性的pod安全标准,导致其
Pod 无法成功调度。
请修改该 Deployment 配置,使其符合受限标准,并验证 Pod 能够正常启动和运行。
提示: Deployment 的配置文件位于/home/candidate/kssc00160/nginx-unprivileged.yaml
创建这个yaml时会报错
Error from server (Forbidden): error when creating “nginx-unprivileged.yaml”: pods “nginx
unprivileged” is forbidden:
violates PodSecurity “restricted:latest”:
allowPrivilegeEscalation != false (container “nginx” must set
securityContext.allowPrivilegeEscalation=false),
securityContext.capabilities.drop=[“ALL”] is required,
securityContext.runAsNonRoot=true is required,
securityContext.seccompProfile.type must be set to “RuntimeDefault” or “Localhost”
根据报错内容,进行字段添加
1 2 3 4 5 6 7 |
securityContext: allowPrivilegeEscalation: false # 禁止权限提升 capabilities: drop: ["ALL"] # 删除所有 capabilities runAsNonRoot: true # 以非 root 用户运行 seccompProfile: type: RuntimeDefault # 使用默认 seccomp 配置 |
欢迎来撩 : 汇总all
