话不多说,直接用图说话
需要详细题库和解题步骤的或者需要模拟环境的可以加我V咨询:kv123123v
题目目录
1、kube-bench 修复不安全项
2、Pod 指定ServiceAccount
3、默认网络策略
4、RBAC-rolebinding
5、日志审计log audit
6、创建Secret
7、Dockerfile检测
8、沙箱运行容器 gVisor
9、网络策略 NetworkPolicy
10、Trivy 扫描镜像安全漏洞
11、AppArmor
12、Sysdig & falor
13、Container 安全上下文
14、TLS安全配置
15、启用API server认证
16、ImagePolicyWebhook容器镜像扫描
1、kube-bench 修复不安全项
linux@node1:~$ kubectl config use-context k8s
linux@node1:~$ ssh master
linux@master:~$ sudo -i
1、 修改api-server /etc/kubernetes/manifests/kube-apiserver.yaml
root@master:~# cp /etc/kubernetes/manifests/kube-apiserver.yaml /tmp
root@master:~# vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --authorization-mode=AlwaysAllow # 改为 --authorization-mode=Node,RBAC
2、修改kubelet /var/lib/kubelet/config.yaml
#检查配置文件位置
root@master:~# systemctl cat kubelet
root@master:~# cp /var/lib/kubelet/config.yaml /tmp
root@master:~# vim /var/lib/kubelet/config.yaml
3、修改etcd /etc/kubernetes/manifests/etcd.yaml
root@master:~# cp /etc/kubernetes/manifests/etcd.yaml /tmp
root@master:~# vim /etc/kubernetes/manifests/etcd.yaml
- --client-cert-auth=true #修改为 true
4、重启
root@master:~# systemctl daemon-reload
root@master:~# systemctl restart kubelet
root@master:~# exit
linux@master:~$ exit
注意:至少等5分钟
2、Pod 指定ServiceAccount
# 切换集群
candidate@node01:~$ kubectl config use-context KSCH00301
# 1、创建SA vim qa-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend-sa
namespace: qa
automountServiceAccountToken: false
linux@node1:~$ kubectl apply -f qa-sa.yaml
linux@node1:~$ kubectl get sa -n qa
2、创建Pod使用该sa
linux@node1:~$ vim /cks/sa/pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: backend
namespace: qa #注意命名空间是否正确
spec:
serviceAccountName: backend-sa # 没有则添加一行,有则修改这一行为刚才创建的 ServiceAccount(考试时,默认已有这一行,需要修改。)
containers:
- image: nginx:1.9
imagePullPolicy: IfNotPresent
name: backend
linux@node1:~$ kubectl apply -f /cks/sa/pod1.yaml
linux@node1:~$ kubectl get pods -n qa
3、删除qa中没有使用的SA
linux@node1:~$ kubectl get sa -n qa
linux@node1:~$ kubectl get pods -n qa -o yaml | grep -i ServiceAccountName
linux@node1:~$ kubectl delete sa test01 -n qa
3、默认网络策略
linux@node1:~$ kubectl config use-context KSCS00101
linux@node1:~$ vim /cks/net/p1.yaml # 修改yaml文件
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: denypolicy # 修改name
namespace: testing # 添加namespace
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
linux@node1:~$ kubectl apply -f /cks/net/p1.yaml
linux@node1:~$ kubectl describe networkpolicy denypolicy -n testing
linux@node1:~$
4、RBAC-rolebinding
linux@node1:~$ kubectl config use-context KSCH00201
linux@node1:~$ kubectl describe rolebinding -n db
linux@node1:~$ kubectl get role -n db
#
1、 编辑 role-1 权限:
linux@node1:~$ kubectl edit role role-1 -n db
rules: #模拟环境里要删除掉 null,然后添加以下内容。考试时,要根据实际情况修改。
- apiGroups: [""]
resources: ["services"]
verbs: ["get"] #这里也是要根据题目实际的要求写,比如题目要求 watch 权限,则这里就将 get 改成 watch。
#对 services 资源 get 操作权限。还可能会考对 endpoints 资源 list 的操作权限,或对 namespace 的 update 权限,要举一反三
2、检查:
linux@node1:~$ kubectl describe role role-1 -n db
3、 在 db 命名空间,创建名为 role-2 的 role,并且通过 rolebinding 绑定 service-account-web,只允许对 namespaces 做 delete 操作。
linux@node1:~$ kubectl create role role-2 --verb=delete --resource=namespaces -n db
linux@node1:~$ kubectl create rolebinding role-2-binding -n db --role=role-2 --serviceaccount=db:service-account-web
检查:
linux@node1:~$ kubectl describe rolebinding -n db
5、日志审计log audit
linux@node1:~$ kubectl config use-context KSH
1、切换到master的root下
linux@node1:~$ ssh master
linux@master:~$ sudo -i
2、配置审计策略
root@master:~# cp /etc/kubernetes/logpolicy/sample-policy.yaml /tmp
root@master:~# vim /etc/kubernetes/logpolicy/sample-policy.yaml # 在行尾插入一下内容
- level: RequestRespone
resources:
- group: ""
resources: ["persistentvolumes"]
- level: Resquest
resources:
- group: ""
resources: ["configmaps"] s
namespace: ["front-apps"]
- level: Metadata
resources:
- group: ""
resources: ["secrets","configmaps"]
- level: Metadata
omitStages:
- "RequestReceived"
3、配置master节点的kube-apiserver.yaml
root@master:~# cp /etc/kubernetes/manifests/kube-apiserver.yaml /tmp
root@master:~# vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --authorization-mode=Node,RBAC #在这一行的后面加参数如果考试中已经存在了则不要重复添加。
/etc/kubernetes/logpolicy/sample-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit-logs.txt
- --audit-log-maxage=10
- --audit-log-maxbackup=2
4、等待api-server自动重启,且恢复正常
# 等待两分钟
root@master:~# kubectl get pods -A
root@master:~# tail /var/log/kubernetes/audit-logs.txt
exit
exit
6、创建Secret
1、将db1-test 的username和password,通过base64解码保存到题目指定文件中
linux@node1:~$ kubectl get secrets db1-test -n istio-system -o jsonpath={.data}
{"password":"aGVsbG8=","username":"ZGIx"}linux@node1:~$
linux@node1:~$ echo 'ZGIx' | base64 -d > /cks/sec/user.txt
linux@node1:~$ echo 'aGVsbG8=' | base64 -d > /cks/sec/pass.txt
# 因为没有回车,所以看起来 db1 会和 linux@node1 在一行。hello 也是这个情况。考试时也是这样的。
linux@node1:~$ cat /cks/sec/user.txt
hellolinux@node1:~$ cat /cks/sec/pass.txt
2、创建名为 db2-test的secret使用题目要求的用户名和密码作为键值
hellolinux@node1:~$ kubectl create secret generic db2-test -n istio-system --from-literal=username=production-instance --from-literal=password=KvLftKgs4aVH
linux@node1:~$ kubectl get secret -n istio-system
3、根据题目要求,参考官网,创建pod使用该sercret
linux@node1:~$ vim k8s-secret.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-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
linux@node1:~$ kubectl apply -f k8s-secret.yaml
linux@node1:~$ kubectl get pod -n istio-system
7、Dockerfile检测
linux@node1:~$ kubectl config use-context KSSC
1、修改dockerfile文件
linux@node1:~$ vim /cks/docker/Dockerfile
FROM ubuntu:16.04 # 改版本 考试的时候是叫你改为22.04
ENTRYPOINT ["/sunnydale.sh"]
USER nobody # 改用户 第十八行左右
CMD ["./sunnydale.sh"]
2、修改deployment.yaml文件
linux@node1:~$ vim /cks/docker/deployment.yaml
2、修改deployment.yaml文件
linux@node1:~$ vim /cks/docker/deployment.yaml
template:
metadata:
labels:
app: couchdb # 这里的run改为app 考试的时候已经是run了
version: stable
spec:
container:
securityContext:
{'capabilities': {'add': ['NET_BIND_SERVICE'], 'drop': ['all']}, 'privileged': False, 'readOnlyRootFilesystem': True, 'runAsUser': 65535}
# 'privileged': False, 'readOnlyRootFilesystem': True, 'runAsUser': 65535
resources:
8、沙箱运行容器 gVisor
linux@node1:~$ kubectl config use-context KSMV
1 、创建RuntimeClass
linux@node1:~$ vim /cks/gVisor/rc.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: untrusted # 用来引用RuntimeClass的名字,RuntimeClass 是一个集群层面的资源
handler: runsc # 添加对应的CRI配置名称
linux@node1:~$ kubectl apply -f /cks/gVisor/rc.yaml
linux@node1:~$ kubectl get RuntimeClass
2、将命名空间为 server 下的 Pod 引用 RuntimeClass
# 修改 3 个 deployment 即可。
linux@node1:~$ kubectl get deploy -n server
# 是编辑 deployment,而不是编辑 pod,要注意。
linux@node1:~$ kubectl edit deploy busybox-run -n server
linux@node1:~$ kubectl edit deploy nginx-host -n server -n server
linux@node1:~$ kubectl edit deploy run-test -n server
spec:
runtimeClassName: untrusted # 在第二个spec下面增加这一行,增加完会跑到下面去
containers:
# 检查
linux@node1:~$ kubectl get deploy -n server -o yaml | grep runtime
runtimeClassName: untrusted
runtimeClassName: untrusted
runtimeClassName: untrusted
9、网络策略 NetworkPolicy
linux@node1:~$ kubectl config use-context KSS
1、检查namespace标签
linux@node1:~$ kubectl get pods -n dev-team --show-labels
2、创建networkpolicy
linux@node1:~$ vim /cks/net/po.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: pod-restriction # 修改名字
namespace: dev-team # 修改名称空间
spec:
podSelector:
matchLabels:
environment: testing # 目标pod kubectl get pods -n dev-team --show-labels查出来的
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: qaqa # 匹配带qaqa的名称空间
- from: # 新加一个from
- namespaceSelector: {}
podSelector:
matchLabels:
environment: testing # 匹配所有带testing标签的pod
linux@node1:~$ kubectl apply -f /cks/net/po.yaml
linux@node1:~$ kubectl get networkpolicy -n dev-team
10、Trivy 扫描镜像安全漏洞
linux@node1:~$ kubectl config use-context KSSC
考试时按照这个来:
linux@node1:~$ kubectl config use-context KK
linux@node1:~$ ssh master
linux@master:~$ kubectl get pods --namespace kamino --output=custom-columns="NAME:.metadata.name,IMAGE:.spec.containers[*].image"
NAME IMAGE
tri111 amazonlinux:1
tri222 amazonlinux:2,nginx:1.19
tri333 vicuu/nginx:host,amazonlinux:2
tri444 amazonlinux:2
linux@master:~$ trivy image amazonlinux:1 | grep -iE 'High|Critical' > amazonlinux:1.txt
linux@master:~$ cat amazonlinux:1.txt # 看HIGH和CRITICAL 是不是0 是就代表没有,不是就代表有需要删除
linux@master:~$ trivy image amazonlinux:2 | grep -iE 'High|Critical' > amazonlinux:2.txt
linux@master:~$ trivy image nginx:1.19 | grep -iE 'High|Critical' >nginx:1.19.txt
linux@master:~$ trivy image vicuu/nginx:host | grep -iE 'High|Critical' >vicuu/nginx:host.txt
linux@master:~$ cat 这几个文件同样是看high和critical
# 删除有漏洞的pod
linux@master:~$ kubectl delete pod -n kamino tri222 # 其他有的也需要删除
11、AppArmor
1、切换到node2上的root下
linux@node1:~$ kubectl config use-context KSSH
linux@node1:~$ ssh node2
2、切换到/etc/apparmor.d/下
root@node2:~#
root@node2:~# cd /etc/apparmor.d/
root@node2:/etc/apparmor.d# cat nginx_apparmor
#include <tunables/global>
profile nginx-profile-3 flags=(attach_disconnected) {#nginx-profile-3就是这个配置文件的名字
#include <abstractions/base>
file,
# Deny all file writes.
deny /** w,
}
3、执行 apparmor 策略模块
root@node2:/etc/apparmor.d# apparmor_status | grep nginx-profile-3
# 没有 grep 到,说明没有启动。 #这个 nginx-profile-3 是/etc/apparmor.d/nginx_apparmor 里的配置的名字,即第一行 profile 后面紧跟的单词。
root@node2:/etc/apparmor.d# apparmor_parser /etc/apparmor.d/nginx_apparmor
# 加载启用这个配置文件
root@node2:/etc/apparmor.d# apparmor_status | grep nginx-profile-3
nginx-profile-3
# 再次检查有结果了
4、修改pod文件
root@node2:/etc/apparmor.d# exit
linux@node2:~$ exit
linux@node1:~$ vim /cks/KSSH00401/nginx-deploy.yaml
apiVersion: v1
kind: Pod
metadata:
name: podx
annotations:
# Tell Kubernetes to apply the AppArmor profile "k8s-apparmor-example-deny-write".
container.apparmor.security.beta.kubernetes.io/podx: localhost/nginx-profile-3
# 添加 annotations,kubernetes.io/podx 名字要和 containers 里的 name 一样,nginx-profile-3 为前面在 worker node2 上执行的 apparmor 策略模块的名字。
spec:
containers:
- image: busybox
imagePullPolicy: IfNotPresent
name: podx
command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 5h" ]
resources: {}
nodeName: node2
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
linux@node1:~$ kubectl apply -f /cks/KSSH00401/nginx-deploy.yaml
pod/podx created
# 可以验证一下
linux@node1:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
podx 1/1 Running 0 99s
redis123-56c7cd579-wzk9f 1/1 Running 3 (38m ago) 26d
# 可以通过检查该配置文件的 proc attr 来验证容器是否实际使用该配置文件运行:
linux@node1:~$ kubectl exec podx -- cat /proc/1/attr/current
nginx-profile-3 (enforce)
12、Sysdig & falor
kubectl config use-context KSSC00401
ssh node2
sudo -i
crictl ps | grep redis123
root@node2:~# crictl info | grep sock # 找到 containerd 的 socke
"containerdEndpoint": "/run/containerd/containerd.sock",
sysdig -M 30 -p "%evt.time,%user.name,%proc.name" --cri /run/containerd/containerd.sock container.name=redis123 >> /opt/KSR00101/incidents/summary
sysdig -M 30 -p "%evt.time,%user.uid,%proc.name" --cri /run/containerd/containerd.sock container.name=redis123 >> /opt/KSR00101/incidents/summary
# 注意:如果考试时执行 sysdig 报错“Unable to load the driver”,则执行下面一条命令:(模拟环境里不需要执行)
#启用模块
# sysdig-probe-loader
# 然后再次执行 sysdig -M 30 ……
# 如果还是报错,就重装一下 sysdig,命令为 apt install sysdig
# 查看保存的文件
head /opt/KSR00101/incidents/summary
exit
exit
13、Container 安全上下文
linux@node1:~$ kubectl config use-context KSMV
linux@node1:~$ kubectl get deploy -n sec-ns
linux@node1:~$ kubectl edit deploy secdep -n sec-ns
name: sec-ctx-demo-1 # 在name下增加一下三行
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
resources: {}
name: sec-ctx-demo-2 # # 在name下增加一下三行
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
resources: {}
securityContext:# 修改这一行增加一下一行
runAsUser: 30000
terminationGracePeriodSeconds: 30
linux@node1:~$ kubectl get pods,deploy -n sec-ns
14、TLS安全配置
linux@node1:~$ kubectl config use-context KSRS
# 切换到master的root下
1、切换到master的root下
linux@node1:~$ ssh master
linux@master:~$ sudo -i
2、修改kube-apiserver
# 修改之前先备份,不要备份到/etc/kubernetes/下,会导致异常
root@master:~# cp /etc/kubernetes/manifests/kube-apiserver.yaml /tmp
root@master:~# vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --tls-cipher-suites=TLS_AES_128_GCM_SHA256
- --tls-min-version=VersionTLS13 # #如果题目要求 TLS 1.2,则就写 VersionTLS12
3、修改etcd.yaml
root@master:~# cp /etc/kubernetes/manifests/etcd.yaml /tmp
root@master:~# vim /etc/kubernetes/manifests/etcd.yaml
- --cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 # 在crt下面的一行添加或修改这一行
root@master:~# systemctl daemon-reload
root@master:~# systemctl restart kubelet
# 修改完成后,需要等待 5 分钟,等集群应用策略后,再检查一下所有 pod,特别是 etcd 和 kube-apiserver 两个 pod,确保模拟环境是正常的。
root@master:~# kubectl -n kube-system get pod
root@master:~# exit
linux@master:~$ exit
15、启用API server认证
root@master:~# kubectl config use-context KSCF
linux@node1:~$ ssh master
linux@master:~$ sudo -i
root@master:~# cp /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
root@master:~# vim /etc/kubernetes/manifests/kube-apiserver.yaml
#注意,只保留 Node,RBAC 这两个,中间是英文逗号。
- --authorization-mode=Node,RBAC
- --enable-admission-plugins=NodeRestriction # AlwaysAdmit修改为 NodeRestriction
- --anonymous-auth=false # 将 true 修改为 false、考试时先检查有没有有这一行没有就添加
root@master:~# systemctl daemon-reload
root@master:~# systemctl restart kubelet
kubectl --kubeconfig=/etc/kubernetes/admin.conf get pod -A
# 删除题目要求的角色绑定
root@master:~# kubectl --kubeconfig=/etc/kubernetes/admin.conf get clusterrolebinding system:anonymous
root@master:~# kubectl --kubeconfig=/etc/kubernetes/admin.conf delete clusterrolebinding system:anonymous
root@master:~# kubectl --kubeconfig=/etc/kubernetes/admin.conf get clusterrolebinding system:anonymous
root@master:~# exit
linux@master:~$ exit
16、ImagePolicyWebhook容器镜像扫描
# 切换考试集群
linux@node1:~$ kubectl config use-context KSSH
1、切换到master的root下
linux@node1:~$ ssh master
linux@master:~$ sudo -i
2、编辑 admission_configuration.json(题目会给这个目录),修改 defaultAllow 为 false:
root@master:~# vim /etc/kubernetes/epconfig/admission_configuration.json
{
"imagePolicy": {
"kubeConfigFile": "/etc/kubernetes/epconfig/kubeconfig.yml",
"allowTTL": 50,
"denyTTL": 50,
"retryBackoff": 500,
"defaultAllow": false # true改为false
}
}
3 、编辑/etc/kubernetes/epconfig/kubeconfig.yml,添加 webhook server 地址:操作前,先备份配置文件
root@master:~# cp /etc/kubernetes/epconfig/kubeconfig.yml /tmp
root@master:~# vim /etc/kubernetes/epconfig/kubeconfig.yml
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority: /etc/kubernetes/epconfig/server.crt
# 在name前面添加webhook server 地址
server: https://image-bouncer-webhook.default.svc:1323/image_policy
name: bouncer_webhook
contexts:
- context:
cluster: bouncer_webhook
user: api-server
name: bouncer_validator
current-context: bouncer_validator
preferences: {}
users:
- name: api-server
user:
client-certificate: /etc/kubernetes/pki/front-proxy-client.crt
client-key: /etc/kubernetes/pki/front-proxy-client.key
#4、编辑 kube-apiserver.yaml,从官网中引用 ImagePolicyWebhook 的配置信息:
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 11.0.1.111:6443
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=11.0.1.111
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook # 追加ImagePolicyWebhook
- --admission-control-config-file=/etc/kubernetes/epconfig/admission_configuration.json # 添加这一行
5 、等待 apiserver 自动重启,且恢复正常。
# 配置完后,重启一下 kubelete 服务
root@master:~# systemctl daemon-reload
root@master:~# systemctl restart kubelet
root@master:~# kubectl get pods -n kube-system
# 通过尝试部署易受攻击的资源 /cks/img/web1.yaml 来测试配置是否有效
root@master:~# kubectl apply -f /cks/img/web1.yaml
6、退回到原 ssh 终端
root@master:~# exit
linux@master:~$ exit