CKS 题库 1、kube-bench 修复不安全项
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
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
重载配置 重启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
Context
您组织的安全策略包括:
- ServiceAccount不得自动挂载API凭据
- ServiceAccount名称必须以“-sa”结尾
清单文件 /cks/sa/pod1.yaml 中指定的Pod由于ServiceAccount指定错误而无法调度。
请完成以下项目:
Task
- 在现有namespace qa 中创建一个名为 backend-sa 的新ServiceAccount,
确保此ServiceAccount不自动挂载API凭据。 - 使用 /cks/sa/pod1.yaml 中的清单文件来创建一个Pod。
- 最后,清理 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
使用该SA创建 pod
vim /cks/sa/pod1.yaml
……
metadata:
name: backend
namespace: qa #注意命名空间是否对
spec:
serviceAccountName: backend-sa # 没有则添加一行,有则修改这一行为刚才创建的ServiceAccount(考试时,默认已有这一行,需要修改。)
containers:
……
删除未使用的 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
CKS 题库 3、默认网络策略
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
CKS 题库 4、RBAC - RoleBinding
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
检查
kubectl -n db describe role role-1
在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
CKS 题库 5、日志审计 log audit
Task
在cluster中启用审计日志。为此,请启用日志后端,并确保:
- 日志存储在 /var/log/kubernetes/audit-logs.txt
- 日志文件能保留 10 天
- 最多保留 2 个旧审计日志文件
/etc/kubernetes/logpolicy/sample-policy.yaml 提供了基本策略。它仅指定不记录的内容。
注意:基本策略位于 cluster 的 master 节点上。
编辑和扩展基本策略以记录:
- RequestResponse 级别的 persistentvolumes 更改
- namespace front-apps 中 configmaps 更改的请求体
- 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
CKS 题库 6、创建 Secret
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检测
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
CKS 题库 8、沙箱运行容器 gVisor
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
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里的混淆。
创建 检查
kubectl apply -f /cks/net/po.yaml
kubectl get networkpolicy -n dev-team
CKS 题库 10、Trivy 扫描镜像安全漏洞
Task:
使用 Trivy 开源容器扫描器检测 namespace kamino 中 具有严重漏洞的镜像 的 Pod。
查找具有 High 或 Critical 严重性漏洞的镜像,并删除使用这些镜像的 Pod 。
注意:Trivy 仅安装在 cluster 的 master 节点上,
在工作节点上不可使用。
你必须切换到 cluster 的 master 节点才能使用 Trivy
参考资料:
https://kubernetes.io/zh-cn/docs/reference/kubectl/cheatsheet/#格式化输出
解答:
-
切换集群
kubectl config use-context KSSC00401
-
查看namespace下pod 和image
kubectl get pods -n kamino -o=custom-columns="NAME:.metadata.name,IMAGE:.spec.containers[*].image"
-
提取镜像名并进行扫描
kubectl describe pod -n kamino | grep -i image: |awk '{print $2}' | sort -u
扫描并显示结果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
可以看到除了amazonlinux:2 其他镜像都存在高危漏洞, 对应之前的pod和images列表 删除包含漏洞的image即可 -
删除包含漏洞的pod
kubectl -n kamino delete pod tri111 tri222 tri333
CKS 题库 11、AppArmor
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这个工作节点。
参考:
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,
}
执行 并 检查 apparmor策略模块
apparmor_parser -q /etc/apparmor.d/nginx_apparmor
apparmor_status | grep nginx-profile-3
修改 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)
创建文件提示权限不足
CKS 题库 12、Sysdig & falco
Task:
使用运行时检测工具来检测 Pod tomcat123 单个容器中频发生成和执行的异常进程。
有两种工具可供使用:
- sysdig
- falco
注: 这些工具只预装在 cluster 的工作节点 node02 上,不在 master 节点。
使用工具至少分析 30 秒 ,使用过滤器检查生成和执行的进程,将事件写到 /opt/KSR00101/incidents/summary 文件中,
其中包含检测的事件, 格式如下:
timestamp , uid/username , processName
保持工具的原始时间戳格式不变。
注: 确保事件文件存储在集群的工作节点上。
请注意,考试时,考题里已表明sysdig在工作节点上,所以你需要ssh到开头写的工作节点上。但在模拟环境,你需要ssh到node02这个工作节点。
解答:
切换集群
kubectl config use-context KSSC00401
切换到 node02 节点 使用root
ssh node02
sudo -i
找到containerd的socket
crictl info | grep sock
使用crictl命令找到容器,题目要求的是tomcat123,则grep tomcat123。
crictl ps | grep tomcat123
注意,考试时,你要通过上面命令grep pod name,然后你要记住的是container name。只是模拟环境里的pod name和container name一样,都是tomcat123。
通过 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安全上下文
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
修改 deployment secdep
kubectl -n sec-ns edit deployment secdep
在template字段下面的spec里面,添加或修改如下红字内容,并保存(考试中也是在Deployment下有两个image的)
请注意,考试和模拟环境中,先检查spec下面(非containers下面)是否有securityContext: {},如果有则可以直接修改即可。否则重复添加是不生效的。
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
CKS 题库 14、启用API server认证
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 #检查
验证
CKS 题库 15、TLS安全配置
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/
解答
切换集群
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
CKS 题库 16、ImagePolicyWebhook容器镜像扫描
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的考试中,默认这行已经添加了,但为了以防万一,模拟环境,没有添加,需要你手动添加。考试时,你先检查,有的话,就不要再重复添加了。重复添加反而会报错!
在kube-apiserver.yaml的 volumeMounts 增加
volumeMounts: #在volumeMounts下面增加 #注意,在1.25考试中,蓝色的内容可能已经有了,你只需要添加绿色字体的内容。可以通过红色字,在文件中定位。但模拟环境没有加,需要你全部手动添加。这样是为了练习,万一考试中没有,你也会加。但是如果考试中已添加,你再添加一遍,则会报错,导致api-server启不起来。
- mountPath: /etc/kubernetes/epconfig #建议紧挨着volumeMounts的下方增加
name: epconfig
readOnly: true
在kube-apiserver.yaml的volumes 增加
volumes: #在volumes下面增加 #注意,在1.25考试中,蓝色的内容可能已经有了,你只需要检查确认一下是否准确。可以通过红色字,在文件中定位。但模拟环境没有加,需要你全部手动添加。这样是为了练习,万一考试中没有,你也会加。但是如果考试中已添加,你再添加一遍,则会报错,导致api-server启不起来。
- name: epconfig #建议紧挨着volumes的下方增加
hostPath:
path: /etc/kubernetes/epconfig
type: DirectoryOrCreate
#如果你写的是目录,则是DirectoryOrCreate,如果你写的是文件,则是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