Back
Featured image of post 2024 CKS 题库

2024 CKS 题库

CKS是一项基于性能的认证考试,在模拟的真实环境中测试考生对Kubernetes和云安全的知识。获得CKS证书表明学员具备在构建、部署和运行时保护基于容器的应用程序和Kubernetes平台的必要能力,并有资格在专业环境中执行这些任务。

CKS 题库 1、kube-bench 修复不安全项

file

Context:

针对 kubeadm创建的 cluster运行CIS基准测试工具时,发现了多个必须立即解决的问题。

Task:

通过配置修复所有问题并重新启动受影响的组件以确保新的设置生效。

修复针对 API 服务器发现的所有以下违规行为:
1.2.7 Ensure that the –authorization-mode argument is not set to AlwaysAllow FAIL
1.2.8 Ensure that the –authorization-mode argument includes Node FAIL
1.2.9 Ensure that the –authorization-mode argument includes RBAC FAIL
1.2.18 Ensure that the –insecure-bind-address argument is not set FAIL (1.25中这项题目没给出,但最好也检查一下,模拟环境里需要改)
~~1.2.19 Ensure that the –insecure-port argument is set to 0 FAIL ~~(1.25中这项题目没给出,不需要再修改了)

修复针对kubelet发现的所有以下违规行为:
Fix all of the following violations that were found against the kubelet:
4.2.1 Ensure that the anonymous-auth argument is set to false FAIL
4.2.2 Ensure that the –authorization-mode argument is not set to AlwaysAllow FAIL
注意:尽可能使用 Webhook 身份验证/授权。

修复针对etcd发现的所有以下违规行为:
Fix all of the following violations that were found against etcd:
2.2 Ensure that the –client-cert-auth argument is set to true FAIL


参考:

https://kubernetes.io/zh/docs/reference/config-api/kubelet-config.v1beta1/


解答:

切换集群

kubectl config use-context KSCS00201
1. 修改api-server
kube-bench master

检查FAIL项,并根据题目要求进行修改

备份文件 /etc/kubernetes/manifests/kube-apiserver.yaml
修改文件内容

- --authorization-mode=Node,RBAC  #修改参数为Node,RBAC
- --insecure-bind-address=0.0.0.0 #删除这一行 #
2. 修改kubelet
kube-bench node

检查FAIL项,并根据题目修改对应项

systemctl status kubelet

file
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf中你也会看到Environment=“KUBELET_CONFIG_ARGS=–config=*/var/lib/kubelet/config.yaml*"。
所以去修改这个文件
修改之前,备份一下配置文件。

vim /var/lib/kubelet/config.yaml

file

重载配置 重启kubelet服务

systemctl daemon-reload
systemctl restart kubelet.service
3. 修改 etcd
kube-bench

备份文件 /etc/kubernetes/manifests/etcd.yaml

修改

- --client-cert-auth=true #修改为true

做完以后要检查一下 apiserver 运行正常


CKS 题库 2、Pod指定ServiceAccount

file

Context

您组织的安全策略包括:

  • ServiceAccount不得自动挂载API凭据
  • ServiceAccount名称必须以“-sa”结尾

清单文件 /cks/sa/pod1.yaml 中指定的Pod由于ServiceAccount指定错误而无法调度。

请完成以下项目:

Task
  1. 在现有namespace qa 中创建一个名为 backend-sa 的新ServiceAccount,
    确保此ServiceAccount不自动挂载API凭据。
  2. 使用 /cks/sa/pod1.yaml 中的清单文件来创建一个Pod。
  3. 最后,清理 namespace qa 中任何 未使用的 ServiceAccount。

参考:

https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-service-account/#使用默认的服务账户访问-api-服务器


解答:

切换集群

kubectl config use-context KSCH00301
创建 ServiceAccount
vi qa-sa.yaml

qa-sa.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: backend-sa  #修改为 对应的name
  namespace: qa     #namespace名称
automountServiceAccountToken: false  #false为不自动挂载secret

应用 并 检查

kubectl -f qa-sa.yaml create
kubectl -n qa get sa

file

使用该SA创建 pod
vim /cks/sa/pod1.yaml
……
metadata:
  name: backend
  namespace: qa #注意命名空间是否对
spec:
  serviceAccountName: backend-sa # 没有则添加一行,有则修改这一行为刚才创建的ServiceAccount(考试时,默认已有这一行,需要修改。)
containers:
……

file

删除未使用的 ServiceAccount

查看所有 SA

kubectl -n qa get sa

过滤已经在用的 SA

kubectl -n qa get pod -o yaml | grep -i serviceAccountName

删除不用的sa

kubectl -n qa delete sa test01

file


CKS 题库 3、默认网络策略

file

Context

一个默认拒绝(default-deny)的NetworkPolicy可避免在未定义任何其他NetworkPolicy的namespace中意外公开Pod。

Task

为所有类型为 Ingress+Egress 的流量在 namespace testing 中创建一个名为 denypolicy 的新默认拒绝 NetworkPolicy 。
此新的 NetworkPolicy 必须拒绝 namespace testing 中的所有的 Ingress + Egress 流量。
将新创建的默认拒绝 NetworkPolicy 应用在 namespace testing 中运行的所有 Pod 。

你可以在 /cks/net/p1.yaml 找到一个模板清单文件。


参考:

https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/#默认拒绝所有入口和所有出站流量


解答:

切换集群

kubectl config use-context KSCS00101

编辑模板文件 /cks/net/p1.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: denypolicy     #注意修改name
  namespace: testing   #添加namespace
spec:
  podSelector: {}
  policyTypes:
  - Ingress            #注意看题,是Ingress + Egress(入口+出口),还是只是Ingress或只是Egress。
  - Egress             #在1.25的考试中,只要求拒绝所有Egress流量,那就只写这这个- Egress即可,这种情况就不要写- Ingress了。

创建并检查

kubectl -f /cks/net/p1.yaml create
kubectl -n testing describe networkpolicies denypolicy

file
file


CKS 题库 4、RBAC - RoleBinding

file

Context

绑定到 Pod 的 ServiceAccount 的 Role 授予过度宽松的权限。完成以下项目以减少权限集。

Task

一个名为 web-pod 的现有 Pod 已在 namespace db 中运行。
编辑绑定到 Pod 的 ServiceAccount service-account-web 的现有 Role,仅允许只对 services 类型的资源执行 get 操作。
在 namespace db 中创建一个名为 role-2 ,并仅允许只对 namespaces 类型的资源执行 delete 操作的新 Role。
创建一个名为 role-2-binding 的新 RoleBinding,将新创建的 Role 绑定到 Pod 的 ServiceAccount。

注意:请勿删除现有的 RoleBinding。


参考

https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/#role-and-clusterole

https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/#一些命令行工具


解答:

切换集群

kubectl config use-context KSCH00201

查看 ServiceAccount rolebinding 对应关系

kubectl -n db describe rolebindings

编辑 role-1 权限

kubectl -n db edit role role-1

添加如下

rules:
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get

file

检查

kubectl -n db describe role role-1

file

在db命名空间,创建名为role-2的role,并且通过rolebinding绑定service-account-web,只允许对namespaces做delete操作。

记住 –verb是权限,可能考delete或者update等 –resource是对象,可能考namespaces或者persistentvolumeclaims等。

kubectl -n db create role role-2 --verb=delete --resource=namespaces
kubectl -n db create rolebinding role-2-binding --role=role-2 --serviceaccount=db:service-account-web

检查

kubectl -n db describe rolebindings

file


CKS 题库 5、日志审计 log audit

file

Task

在cluster中启用审计日志。为此,请启用日志后端,并确保:

  • 日志存储在 /var/log/kubernetes/audit-logs.txt
  • 日志文件能保留 10
  • 最多保留 2 个旧审计日志文件

/etc/kubernetes/logpolicy/sample-policy.yaml 提供了基本策略。它仅指定不记录的内容。

注意:基本策略位于 cluster 的 master 节点上。


编辑和扩展基本策略以记录:

  • RequestResponse 级别的 persistentvolumes 更改
  • namespace front-appsconfigmaps 更改的请求体
  • Metadata 级别的所有 namespace 中的 ConfigMap 和 Secret 的更改

此外,添加一个全方位的规则以在 Metadata 级别记录所有其他请求。

注意:不要忘记应用修改后的策略。


参考

https://kubernetes.io/zh/docs/tasks/debug/debug-cluster/audit/


解答:

日志审计这一题需要自己调整的内容还是挺多的,因此要非常仔细,建议修改前备份一下原始的环境,要不然修改错了就会导致集群崩溃。

切换集群

kubectl config use-context KSCH00601
切换到Master的root下
ssh master01
sudo -i
配置审计策略

先备份配置文件

cp /etc/kubernetes/logpolicy/sample-policy.yaml bak/
vim /etc/kubernetes/logpolicy/sample-policy.yaml

不要删除原有规则, 可以在下面继续追加题目要求的规则

  - level: RequestResponse
    resources:
    - group: ""
      resources: ["persistentvolumes"] #根据题目要求修改,比如题目要求的是namespaces。

  - level: Request
    resources:
    - group: ""
      resources: ["configmaps"] #根据题目要求修改,比如题目要求的是persistentvolumes或者pods。
    namespaces: ["front-apps"]

  - level: Metadata
    resources:
    - group: ""
      resources: ["secrets", "configmaps"]

  - level: Metadata
    omitStages:
      - "RequestReceived"
配置 master 节点的kube-apiserver.yaml
cp /etc/kubernetes/manifests/kube-apiserver.yaml bakyaml/
vi /etc/kubernetes/manifests/kube-apiserver.yaml

添加以下参数:注意空格要对齐,不建议放到最后,建议按照下图的位置放这四条信息。

定义审计策略yaml文件位置,通过hostpath挂载

- --audit-policy-file=/etc/kubernetes/logpolicy/sample-policy.yaml #主意检查,如果考试中已经存在了,则不要重复添加。
#定义审计日志位置,通过hostpath挂载
- --audit-log-path=/var/log/kubernetes/audit-logs.txt #主意检查,如果考试中已经存在了,则不要重复添加。
#定义保留旧审计日志文件的最大天数为10天
- --audit-log-maxage=10 #主意检查,如果考试中已经存在了,则不要重复添加。
#定义要保留的审计日志文件的最大数量为2个
- --audit-log-maxbackup=2 #主意检查,如果考试中已经存在了,则不要重复添加。
volumeMounts: #找到这个字段,添加下面内容
- mountPath: /etc/kubernetes/logpolicy/sample-policy.yaml #这里也可以写到目录/etc/kubernetes/logpolicy/
  name: audit #注意,在1.25考试中,蓝色的内容已经默认有了,你只需要添加绿色字体的内容。可以通过红色字,在文件中定位。但模拟环境没有加,需要你全部手动添加。这样是为了练习,万一考试中没有,你也会加。但是如果考试中已添加,你再添加一遍,则会报错,导致api-server启不起来。
  readOnly: true #这个为true
- mountPath: /var/log/kubernetes/
  name: audit-log #注意,在1.25考试中,蓝色的内容已经有了,你只需要添加绿色字体的内容。可以通过红色字,在文件中定位。但模拟环境没有加,需要你全部手动添加。这样是为了练习,万一考试中没有,你也会加。
  readOnly: false #这个为false
volumes: #找到这个字段,添加下面内容 #注意,在1.25考试中,蓝色的内容已经有了,volumes这段无需修改,但是为了以防万一,模拟环境中没有加,需要你手动添加。这样是为了练习,万一考试中没有,你也会加。
- name: audit
  hostPath:
  path: /etc/kubernetes/logpolicy/sample-policy.yaml #这里如果写到目录/etc/kubernetes/logpolicy/,则下面的type:应为type: DirectoryOrCreate
  type: File
- name: audit-log
  hostPath:
  path: /var/log/kubernetes/
  type: DirectoryOrCreate

重启kubelet服务, 等待2分钟后,再检查

systemctl restart kubelet
kubectl get pod -A
tail /var/log/kubernetes/audit-logs.txt

file


CKS 题库 6、创建 Secret

file

Task

在 namespace istio-system 中获取名为 db1-test 的现有 secret 的内容
username 字段存储在名为 /cks/sec/user.txt 的文件中,并将password 字段存储在名为 /cks/sec/pass.txt 的文件中。
注意:你必须创建以上两个文件,他们还不存在。

注意:不要在以下步骤中使用/修改先前创建的文件,如果需要,可以创建新的临时文件。

istio-system namespace 中创建一个名为 db2-test 的新 secret ,内容如下:
username : production-instance
password : KvLftKgs4aVH
最后,创建一个新的 Pod ,它可以通过卷访问 secret db2-test
Pod 名称 secret-pod
Namespace istio-system
容器名 dev-container
镜像 nginx
卷名 secret-volume
挂载路径 /etc/secret


参考

https://kubernetes.io/zh/docs/tasks/configmap-secret/managing-secret-using-kubectl/#decoding-secret

https://kubernetes.io/zh/docs/tasks/configmap-secret/managing-secret-using-kubectl/#create-a-secret

https://kubernetes.io/zh/docs/concepts/configuration/secret/#using-secrets


解答:

切换集群

kubectl config use-context KSCH00701

将db1-test的username和password,通过base64解码保存到题目指定文件:

kubectl -n istio-system get secrets db1-test -o jsonpath={.data.username} | base64 -d > /cks/sec/user.txt
kubectl -n istio-system get secrets db1-test -o jsonpath={.data.password} | base64 -d > /cks/sec/pass.txt

检查

cat /cks/sec/user.txt
cat /cks/sec/pass.txt

创建名为 db2-test 的 secret 使用题目要求的用户名和密码作为键值。注意要加命名空间。

注意,如果密码中有特殊字符(例如:$,\,*,= 和 !),需要加单引号来转义–from-literal=password=‘G!Y*d$zDsb’这样

kubectl -n istio-system create secret generic db2-test --from-literal username=production-instance --from-literal assword=KvLftKgs4aVH
kubectl -n istio-system get secret

根据题目要求,参考官网,创建Pod使用该secret

vim k8s-secret.yaml

k8s-secret.yaml

apiVersion: v1
kind: Pod
metadata:
  name: secret-pod          #pod名字
  namespace: istio-system   #命名空间
spec:
  containers:
  - name: dev-container     #容器名字
    image: nginx            #镜像名字
    volumeMounts:
    - name: secret-volume   #卷名
      mountPath: "/etc/secret"  #挂载路径
  volumes:
  - name: secret-volume     #卷名
    secret:
      secretName: db2-test  #名为 db2-test 的 secret
kubectl -f k8s-secret.yaml create
kubectl -n istio-system get pod

CKS 题库 7、Dockerfile检测

file

Task

分析和编辑给定的Dockerfile /cks/docker/Dockerfile(基于ubuntu:16.04 镜像),
并修复在文件中拥有的突出的安全/最佳实践问题的两个指令。

分析和编辑给定的清单文件 /cks/docker/deployment.yaml ,
并修复在文件中拥有突出的安全/最佳实践问题的两个字段。

注意:请勿添加或删除配置设置;只需修改现有的配置设置让以上两个配置设置都不再有安全/最佳实践问题。

注意:如果您需要非特权用户来执行任何项目,请使用用户ID 65535 的用户 nobody 。

只修改即可,不需要创建。


参考

https://kubernetes.io/zh/docs/concepts/security/pod-security-standards/#restricted


解答:

切换集群

kubectl config use-context KSSC00301

修改Dockerfile

vim /cks/docker/Dockerfile
#修改基础镜像为题目要求的 ubuntu:16.04
FROM ubuntu:16.04

#仅将CMD上面的USER root修改为USER nobody,不要改其他的USER root。
USER nobody

修改deployment.yaml

vim /cks/docker/deployment.yaml
template里标签跟上面的内容不一致,所以需要将原先的run: couchdb修改为app: couchdb
app: couchdb
注意,这里具体要改成app: couchdb还是其他的标签,要以考试给你的yaml文件的上下文其他标签为准,要与另外两个标签一致,具体见下方截图。)
感谢网友Tse和adams的反馈和纠正。

删除 'SYS_ADMIN' 字段,确保 'privileged': 为False 。
(CKS考试是有多套类似考试环境的,所以有时是删SYS_ADMIN,有时是改'privileged': False)
注意 注意,如果考试时,本来就没有'SYS_ADMIN' 字段,且'privileged':也默认就为False,则直接将直接改成如下。
securityContext:
  privileged: False

file
file


CKS 题库 8、沙箱运行容器 gVisor

file

Context

该 cluster 使用 containerd 作为 CRI 运行时。containerd 的默认运行时处理程序是 runc
containerd 已准备好支持额外的运行时处理程序 runsc (gVisor)。

Task

使用名为 runsc 的现有运行时处理程序,创建一个名为 untrusted 的 RuntimeClass。
更新 namespace server 中的所有 Pod 以在 gVisor 上运行。
您可以在 /cks/gVisor/rc.yaml 中找到一个模版清单。


参考

https://kubernetes.io/zh-cn/docs/concepts/containers/runtime-class/#2-创建相应的-runtimeclass-资源


解答:

切换集群

kubectl config use-context KSMV00301

创建RuntimeClass

vim /cks/gVisor/rc.yaml

rc.yaml

apiVersion: node.k8s.io/v1   ##将apiVersion: node.k8s.io/v1beta1修改为apiVersion: node.k8s.io/v1。这个在1.25正式考试的时候,是对的,不需要修改的。
kind: RuntimeClass
metadata:
  name: untrusted # 用来引用 RuntimeClass 的名字,RuntimeClass 是一个集群层面的资源
handler: runsc    # 对应的 CRI 配置的名称
kubectl -f /cks/gVisor/rc.yaml create
kubectl get RuntimeClass

将命名空间为server下的Pod引用RuntimeClass。
考试时,3个Deployment下有3个Pod,修改3个deployment即可。

kubectl -n server get deployment
kubectl -n server edit deployments busybox-run
kubectl -n server edit deployments nginx-host
kubectl -n server edit deployments run-test
spec: #找到这个spec,注意在deployment里是有两个单独行的spec的,要找第二个,也就是下面有containers这个字段的spec。
  runtimeClassName: untrusted #添加这一行,注意空格对齐,保存会报错,忽略即可。
  containers:
  - image: nginx:1.9
    imagePullPolicy: IfNotPresent
    name: run-test

CKS 题库 9、网络策略 NetworkPolicy

file

Task

创建一个名为 pod-restriction 的 NetworkPolicy 来限制对在 namespace dev-team 中运行的 Pod products-service 的访问。
只允许以下 Pod 连接到 Pod products-service

  • namespace qaqa 中的 Pod
  • 位于任何 namespace,带有标签 environment: testing 的 Pod
    注意:确保应用 NetworkPolicy。

你可以在 /cks/net/po.yaml 找到一个模板清单文件。


参考

https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/#networkpolicy-resource


解答:

切换集群

kubectl config use-context KSSH00301

检查namespace标签

模拟环境已提前打好标签了,所以你只需要检查标签即可。但为了防止考试时,没有给你打标签,所以还是需要你将下面打标签的命令记住。

# 查看 qaqa 命名空间标签(name: qaqa)
kubectl get ns --show-labels

# 查看 pod 标签(environment: testing)
kubectl get pod -n dev-team --show-labels

如果 Pod 或者 Namespace 没有标签,则需要打上标签。
注意:我这里将pod products-service的标签打成了environment: testing,下面会有解释,不要和题目里要求的“位于任何namespace,带有标签environment: testing的Pod”这句话里的标签混淆了。

kubectl label ns qaqa name=qaqa
kubectl label pod products-service environment=testing -n dev-team

创建NetworkPolicy

vi /cks/net/po.yaml
metadata:
  name: pod-restriction #修改
  namespace: dev-team #修改
spec:
  podSelector:
  matchLabels:
    environment: testing #根据题目要求的标签修改,这个写的是Pod products-service的标签,也就是使用kubectl get pod -n dev-team --show-labels查出来的pod的标签,这个标签不要和题目里要求的“位于任何namespace,带有标签environment: testing的Pod”这句话里的标签混淆了,两个没有关系,所以可不一样。比如你考试时查出来的POD products-service的标签是name: products,那这里的environment: testing就要换成name: products。
  policyTypes:
  - Ingress #注意,这里只写 - Ingress,不要将 - Egress也复制进来!
  ingress:
  - from: #第一个from
    - namespaceSelector:
      matchLabels:
        name: qaqa #命名空间有name: qaqa标签的
  - from: #第二个from
    - namespaceSelector: {} #修改为这样,所有命名空间
      podSelector: #注意,这个podSelector前面的“-” 要删除,换成空格,空格对齐要对。
        matchLabels:
          environment: testing #有environment: testing标签的Pod,这个地方是根据题目要求“Pods with label environment: testing , in any namespace”,这句话里的pod标签写的。不要和上面spec里的混淆。

file

创建 检查

kubectl apply -f /cks/net/po.yaml
kubectl get networkpolicy -n dev-team

CKS 题库 10、Trivy 扫描镜像安全漏洞

file

Task:

使用 Trivy 开源容器扫描器检测 namespace kamino 中 具有严重漏洞的镜像 的 Pod。

查找具有 HighCritical 严重性漏洞的镜像,并删除使用这些镜像的 Pod 。

注意:Trivy 仅安装在 cluster 的 master 节点上,
在工作节点上不可使用。
你必须切换到 cluster 的 master 节点才能使用 Trivy


参考资料:

https://kubernetes.io/zh-cn/docs/reference/kubectl/cheatsheet/#格式化输出


解答:
  1. 切换集群

    kubectl config use-context KSSC00401
    
  2. 查看namespace下pod 和image

    kubectl get pods -n kamino -o=custom-columns="NAME:.metadata.name,IMAGE:.spec.containers[*].image"
    

    file

  3. 提取镜像名并进行扫描

    kubectl describe pod -n kamino | grep -i image: |awk '{print $2}' | sort -u
    

    file
    扫描并显示结果

    for i in `kubectl describe pod -n kamino | grep -i image: |awk '{print $2}' | sort -u`; do trivy -q image -s HIGH,CRITICAL $i | grep -iEB3 "HIGH:|CRITICAL:" ; done
    

    file
    可以看到除了amazonlinux:2 其他镜像都存在高危漏洞, 对应之前的pod和images列表 删除包含漏洞的image即可

  4. 删除包含漏洞的pod

    kubectl -n kamino delete pod tri111 tri222 tri333
    

    file


CKS 题库 11、AppArmor

file

Context:

APPArmor 已在 cluster 的工作节点node02上被启用。一个 APPArmor 配置文件已存在,但尚未被实施。

Task:

在 cluster 的工作节点node02上,实施位于 /etc/apparmor.d/nginx_apparmor 的现有APPArmor 配置文件。
编辑位于 /cks/KSSH00401/nginx-deploy.yaml 的现有清单文件以应用 AppArmor 配置文件。
最后,应用清单文件并创建其中指定的 Pod 。

请注意,考试时,考题里已表明APPArmor在工作节点上,所以你需要ssh到开头写的工作节点上。
在模拟环境,你需要ssh到node02这个工作节点。
file


参考:

https://kubernetes.io/zh/docs/tutorials/security/apparmor/#example

解答:

切换集群

kubectl config use-context KSSH00401

连接到 node02 并切换到 root

ssh node02
sudo -i

切换到 apparmor 目录, 并检查配置文件

vi /etc/apparmor.d/etc/apparmor.d/nginx_apparmor

nginx_apparmor

#include <tunables/global>
#nginx-profile-3 #检查这一行是否存在 存在则注释掉
profile nginx-profile-3 flags=(attach_disconnected) {
  #include <abstractions/base>
  file,
  # Deny all file writes.
  deny /** w,
}

file

执行 并 检查 apparmor策略模块

apparmor_parser -q /etc/apparmor.d/nginx_apparmor
apparmor_status | grep nginx-profile-3

file

修改 pod 文件

(注意!注意!考试时,这个文件是在默认登录的终端那个初始节点上的,而不是在这个work节点的)

vi /cks/KSSH00401/nginx-deploy.yaml

添加注解

annotations:
  container.apparmor.security.beta.kubernetes.io/podx: localhost/nginx-profile-3

创建pod

kubectl -f  /cks/KSSH00401/nginx-deploy.yaml create

检查

kubectl get pod
kubectl exec podx -- cat /proc/1/attr/current
kubectl exec podx -- touch /tmp/test

查看current显示 xxx (enforce)
创建文件提示权限不足
file


CKS 题库 12、Sysdig & falco

file

Task:
使用运行时检测工具来检测 Pod tomcat123 单个容器中频发生成和执行的异常进程。
有两种工具可供使用:

  • sysdig
  • falco

注: 这些工具只预装在 cluster 的工作节点 node02 上,不在 master 节点。
使用工具至少分析 30 秒 ,使用过滤器检查生成和执行的进程,将事件写到 /opt/KSR00101/incidents/summary 文件中,
其中包含检测的事件, 格式如下:
timestamp , uid/username , processName

file

保持工具的原始时间戳格式不变。
注: 确保事件文件存储在集群的工作节点上。

请注意,考试时,考题里已表明sysdig在工作节点上,所以你需要ssh到开头写的工作节点上。但在模拟环境,你需要ssh到node02这个工作节点。
file


解答:

切换集群

kubectl config use-context KSSC00401

切换到 node02 节点 使用root

ssh node02
sudo -i

找到containerd的socket

crictl info | grep sock

file

使用crictl命令找到容器,题目要求的是tomcat123,则grep tomcat123。
crictl ps | grep tomcat123

注意,考试时,你要通过上面命令grep pod name,然后你要记住的是container name。只是模拟环境里的pod name和container name一样,都是tomcat123。
file

通过 sysdig 扫描容器30s并输出到指定文件:
sysdig -h 和-l 查看帮助
注:可以使用 sysdig -l |grep time 过滤,确认输出格式字段

sysdig -l | grep time
sysdig -l | grep uid
sysdig -l | grep proc

开始扫描 (我目前想不到别的方法,只能将命令分成2条了,谁有更好的方法,可以分享一下。)
(container.name也可以换成container.id=7cb82fdbc1295。注意要写container name,而不是pod name,只是模拟环境里,pod name和container name一样,都是tomcat123)

sysdig -M 30 -p "%evt.time,%user.uid,%proc.name" --cri /run/containerd/containerd.sock container.name=tomcat123 >> /opt/KSR00101/incidents/summary
sysdig -M 30 -p "%evt.time,%user.name,%proc.name" --cri /run/containerd/containerd.sock container.name=tomcat123 >> /opt/KSR00101/incidents/summary

提示:如果考试时执行sysdig报错“Unable to load the driver”,则执行下面一条命令:(模拟环境里不需要执行)

#启用模块
sysdig-probe-loader

然后再次执行sysdig -M 30 ……

如果还是报错,就重装一下sysdig,命令为 apt install sysdig

查看保存的文件

cat /opt/KSR00101/incidents/summary |head

CKS 题库 13、Container安全上下文

file

Context

Container Security Context应在特定namespace中修改Deployment。

Task

按照如下要求修改 sec-ns 命名空间里的 Deployment secdep

  • 用ID为 30000 的用户启动容器(设置用户ID为: 30000)
  • 不允许进程获得超出其父进程的特权(禁止allowPrivilegeEscalation)
  • 以只读方式加载容器的根文件系统(对根文件的只读权限)

参考

https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/security-context/


解答:

切换集群

kubectl config use-context KSMV00102

file

修改 deployment secdep

kubectl -n sec-ns edit deployment secdep

在template字段下面的spec里面,添加或修改如下红字内容,并保存(考试中也是在Deployment下有两个image的)
请注意,考试和模拟环境中,先检查spec下面(非containers下面)是否有securityContext: {},如果有则可以直接修改即可。否则重复添加是不生效的。

      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true

file


CKS 题库 14、启用API server认证

file

Context

kubeadm 创建的 cluster 的 Kubernetes API 服务器,出于测试目的,
临时配置允许未经身份验证和未经授权的访问,授予匿名用户 cluster-admin 的访问权限.

Task

重新配置 cluster 的 Kubernetes APl 服务器,以确保只允许经过身份验证和授权的 REST 请求。
使用授权模式 Node , RBAC 和准入控制器 NodeRestriction
删除用户 system:anonymous 的 ClusterRoleBinding 来进行清理。

注意:所有 kubectl 配置环境/文件也被配置使用未经身份验证和未经授权的访问。
你不必更改它,但请注意,一旦完成 cluster 的安全加固, kubectl 的配置将无法工作。
您可以使用位于 cluster 的 master 节点上,cluster 原本的 kubectl 配置文件
/etc/kubernetes/admin.conf ,以确保经过身份验证的授权的请求仍然被允许。

模拟环境里,初始化这道题的脚本为b.sh


参考

https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-apiserver/


解答

切换集群

kubectl config use-context KSCF00301

远程到 master 并切换到 root

ssh master01
sudo -i
sh /root/b.sh #模拟这道题的环境

确保只有认证并且授权过的REST请求才被允许
/etc/kubernetes/manifests/kube-apiserver.yaml

- --authorization-mode=AlwaysAllow
- --enable-admission-plugins=AlwaysAdmit

修改为

- --authorization-mode=Node,RBAC 
#注意,只保留Node,RBAC这两个,中间是英文状态下的逗号。在1.25考试中,这一条可能默认已经有了,但还是要检查确认一下。

- --enable-admission-plugins=NodeRestriction 
#在1.25考试中,这一个原先为AlwaysAdmit,需要修改为NodeRestriction。

重启kubelet

systemctl daemon-reload
systemctl restart kubelet
kubectl get pod -A #过几分钟集群才会恢复正常

删除题目要求的角色绑定

kubectl get clusterrolebinding system:anonymous     #检查
kubectl delete clusterrolebinding system:anonymous  #删除
kubectl get clusterrolebinding system:anonymous     #检查

file

验证
file


CKS 题库 15、TLS安全配置

file

Task

通过TLS加强kube-apiserver安全配置,要求

  • kube-apiserver除了 TLS 1.3 及以上的版本可以使用,其他版本都不允许使用。
  • 密码套件(Cipher suite)为 TLS_AES_128_GCM_SHA256

通过TLS加强ETCD安全配置,要求

  • 密码套件(Cipher suite)为 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

参考

https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/

file
file


解答

切换集群

kubectl config user-context KSRS00501

远程到 master 并切换到 root

ssh master01
sudo -i

修改 kube-apiserver, 养成 修改之前备份文件的好习惯

mkdir bakyaml
cp /etc/kubernetes/manifests/kube-apiserver.yaml bakyaml/
vim /etc/kubernetes/manifests/kube-apiserver.yaml

添加或修改相关内容,并保存(先检查一下,如果考试环境里已经给你这两条了,则你只需要修改即可)

    - --tls-cipher-suites=TLS_AES_128_GCM_SHA256
    - --tls-min-version=VersionTLS13

等待3分钟,等集群应用策略后,再检查kube-apiserver,确保Running。

kubectl -n kube-system get pod

修改 ETCD

cp /etc/kubernetes/manifests/etcd.yaml bakyaml/
vim /etc/kubernetes/manifests/etcd.yaml

添加或修改相关内容,并保存

    - --cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

修改完成后,需要等待3分钟,等集群应用策略后,再检查一下所有pod,特别是etcd和kube-apiserver两个pod,确保模拟环境是正常的。

kubectl get pod -A
kubectl -n kube-system get pod

file


CKS 题库 16、ImagePolicyWebhook容器镜像扫描

file

Context

cluster 上设置了容器镜像扫描器,但尚未完全集成到 cluster 的配置中。
完成后,容器镜像扫描器应扫描并拒绝易受攻击的镜像的使用。

Task

注意:你必须在 cluster 的 master 节点上完成整个考题,所有服务和文件都已被准备好并放置在该节点上。

给定一个目录 /etc/kubernetes/epconfig 中不完整的配置,
以及具有 HTTPS 端点 https://image-bouncer-webhook.default.svc:1323/image_policy 的功能性容器镜像扫描器:

  • 启用必要的插件来创建镜像策略
  • 校验控制配置并将其更改为隐式拒绝(implicit deny)
  • 编辑配置以正确指向提供的 HTTPS 端点

最后,通过尝试部署易受攻击的资源 /cks/img/web1.yaml 来测试配置是否有效。


参考

https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/#如何启用一个准入控制器

https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook

https://kubernetes.io/zh/docs/tasks/debug/debug-cluster/audit/#log-后端


解答

切换集群

kubectl config use-context KSSH00901

远程到master并切换root

ssh master01
sudo -i

编辑admission_configuration.json(题目会给这个目录),修改defaultAllow为false:

vi /etc/kubernetes/epconfig/admission_configuration.json
    "denyTTL": 50,
    "retryBackoff": 500,
    "defaultAllow": false #将true改为false

编辑/etc/kubernetes/epconfig/kubeconfig.yml,添加 webhook server 地址:
操作前,先备份配置文件

cp /etc/kubernetes/epconfig/kubeconfig.yml bakyaml/
vi /etc/kubernetes/epconfig/kubeconfig.yml

修改如下内容

    certificate-authority: /etc/kubernetes/epconfig/server.crt
    server: https://image-bouncer-webhook.default.svc:1323/image_policy #添加webhook server地址
  name: bouncer_webhook

编辑kube-apiserver.yaml,从官网中引用 ImagePolicyWebhook 的配置信息:
操作前,先备份配置文件

cp /etc/kubernetes/manifests/kube-apiserver.yaml bakyaml/
vi /etc/kubernetes/manifests/kube-apiserver.yaml

在- command:下添加如下内容,注意空格要对齐(不建议放到最后,建议放置的位置详见下方截图)

- --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook

- --admission-control-config-file=/etc/kubernetes/epconfig/admission_configuration.json
#在1.25的考试中,默认这行已经添加了,但为了以防万一,模拟环境,没有添加,需要你手动添加。考试时,你先检查,有的话,就不要再重复添加了。重复添加反而会报错!

file

在kube-apiserver.yaml的 volumeMounts 增加

volumeMounts: #在volumeMounts下面增加 #注意,在1.25考试中,蓝色的内容可能已经有了,你只需要添加绿色字体的内容。可以通过红色字,在文件中定位。但模拟环境没有加,需要你全部手动添加。这样是为了练习,万一考试中没有,你也会加。但是如果考试中已添加,你再添加一遍,则会报错,导致api-server启不起来。
- mountPath: /etc/kubernetes/epconfig #建议紧挨着volumeMounts的下方增加
name: epconfig
readOnly: true

file

在kube-apiserver.yaml的volumes 增加

volumes: #在volumes下面增加 #注意,在1.25考试中,蓝色的内容可能已经有了,你只需要检查确认一下是否准确。可以通过红色字,在文件中定位。但模拟环境没有加,需要你全部手动添加。这样是为了练习,万一考试中没有,你也会加。但是如果考试中已添加,你再添加一遍,则会报错,导致api-server启不起来。
- name: epconfig #建议紧挨着volumes的下方增加
hostPath:
path: /etc/kubernetes/epconfig
type: DirectoryOrCreate
#如果你写的是目录,则是DirectoryOrCreate,如果你写的是文件,则是File

file

重启并检查集群

systemctl restart kubelet
kubectl -n kube-system get pod

通过尝试部署易受攻击的资源 /cks/img/web1.yaml 来测试配置是否有效
无法创建pod,如下报错,表示成功。
因为模拟环境里的image_policy策略是镜像tag是latest的不允许创建。

kubectl apply -f /cks/img/web1.yaml

file