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   v1.28版本 考题中这项没给出
修复针对 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
做题解答:
#检测:
kube-bench run --targets=master
kube-bench run --targets=node
kube-bench run --targets=etcd
#kube-apiserver配置文件的修改,修改之前,备份一下配置文件
vim /etc/kubernetes/manifests/kube-apiserver.yaml
#修改、添加、删除相关内容 
#修改 authorization-mode,注意 Node 和 RBAC 之间的符号是英文状态的逗号,而不是点。
 - --authorization-mode=Node,RBAC
#删除 insecure-bind-address,考试中,有可能本来就没写这行。
 - --insecure-bind-address=0.0.0.0
#kubelet配置文件的修改,修改之前,备份一下配置文件
vim /var/lib/kubelet/config.yaml
修改
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
 anonymous:  #修改 anonymous 下的,将 true 改为 false
 enabled: false  #改为 false
 webhook:
 cacheTTL: 0s
 enabled: true   #这个 webhook 下的 true 不要改
 x509:
 clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:   #修改 authorization 下的
 mode: Webhook
 webhook:
……
#重启
systemctl daemon-reload
systemctl restart kubelet
#etcd配置文件的修改,修改之前,备份一下配置文件。
vim /etc/kubernetes/manifests/etcd.yaml
修改
 - --client-cert-auth=true #修改为 true
#验证
修改完成后,等待 5 分钟,再检查一下所有 pod,确保模拟环境里的所有 pod 都正常。
kubectl get pod -A

2、Pod 指定 ServiceAccount

Task

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

apiVersion: v1
kind: Namespace
metadata:
  name: qa
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: backend-sa
  namespace: qa
automountServiceAccountToken: false
#创建pod
2-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: qa
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  serviceAccountName: backend-sa
#创建用于模拟的sa
kubectl create sa fraont-sa -n qa
#清理 namespace qa 中任何未使用的 ServiceAccount
kubectl get pod -n qa -o yaml|grep -i "serviceaccount:"
kubectl get sa -n qa
kubectl delete sa fraont-sa -n qa

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 找到一个模板清单文件。
做题解答:
3-netpol.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: testing
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: denypolicy
  namespace: testing
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

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
做题解答:
#创建ns
4-ns.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: db
#创建sa
4-sa.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: service-account-web
  namespace: db
#创建pod
4-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
  namespace: db
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  serviceAccountName: service-account-web
#创建role
4-role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: role1
  namespace: db
rules:
- apiGroups: [""]
  resources: ["services"]
  verbs:
  - get
  - list
#创建rolebinding
4-rolebinding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: role-1-binding
  namespace: db
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: role1
subjects:
- kind: ServiceAccount
  name: service-account-web
  namespace: db
#创建clusterrole
4-clusterrole.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: role2
  namespace: db
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs:
  - delete
#创建clusterrolebinding
4-clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: role-2-binding
  namespace: db
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: role2
subjects:
- kind: ServiceAccount 
  name: service-account-web
  namespace: db

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 级别记录所有其他请求。
注意:不要忘记应用修改后的策略。
做题解答:
#1、策略文件
mkdir -p /var/log/kubernetes
mkdir -p /etc/kubernetes/logpolicy
vim /etc/kubernetes/logpolicy/sample-policy.yaml

apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
  - "RequestReceived"
rules:
  - level: RequestResponse
    resources:
    - group: ""
      resources: ["persistentvolumes"] 
  - level: Request
    resources:
    - group: ""
      resources: ["configmaps"]   
    namespaces: ["front-apps"]
  - level: Metadata
    resources:
    - group: ""
      resources: ["secrets", "configmaps"]
  - level: Metadata
    omitStages:
      - "RequestReceived"
#2、修改kube-apiserver
vim /etc/kubernetes/manifests/kube-apiserver.yaml

#- command部分
- --audit-log-maxage=10
- --audit-log-maxbackup=2
- --audit-policy-file=/etc/kubernetes/logpolicy/sample-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit-logs.txt

#volumeMounts部分
- mountPath: /etc/kubernetes/logpolicy/sample-policy.yaml
  name: audit
  readOnly: true
- mountPath: /var/log/kubernetes/
  name: audit-log
  readOnly: false
  
#volumes部分
- hostPath:
    path: /etc/kubernetes/logpolicy/sample-policy.yaml
    type: File
  name: audit
- hostPath:
    path: /var/log/kubernetes/
    type: DirectoryOrCreate
  name: audit-log

#3、重启kubelet,然后查看下log
systemctl daemon-reload
systemctl restart kubelet
tail -500f /var/log/kubernetes/audit-logs.txt #看下有没有日志

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
做题解答:
#ns
6-ns.yaml 

apiVersion: v1
kind: Namespace
metadata:
  name: istio-system
#仅用于创建之后答题
#secret
6-db1-test.yaml 

apiVersion: v1
kind: Secret
metadata:
  name: db1-test
  namespace: istio-system
type: Opaque
data:
  username: bGFkeV9raWxsZXI5
  password: MTIzNDU2
#解答db1-test部分
kubectl get secret -n istio-system -o yaml
echo xxx | base64 -d
mkdir -p /cks/sec && touch /cks/sec/user.txt && echo lady_killer9 > /cks/sec/user.txt
touch /cks/sec/pass.txt && echo 123456 > /cks/sec/pass.txt
#解答db2-test部分
#secret
6-db2-test.yaml 

apiVersion: v1
kind: Secret
metadata:
  name: db2-test
  namespace: istio-system
type: Opaque
data:
  username: cHJvZHVjdGlvbi1pbnN0YW5jZQo=
  password: S3ZMZnRLZ3M0YVZICg==
#pod
6-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: secret-pod
  namespace: istio-system
spec:
  containers:
  - name: dev-container
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: volume-secret
      mountPath: /etc/secret
  volumes:
  - name: volume-secret
    secret:
      secretName: db2-test
#验证
kubectl exec -it secret-pod -n istio-system -- bash
cat /etc/secret/username
cat /etc/secret/password

7、Dockerfile 检测

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

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

注意:请勿添加或删除配置设置;只需修改现有的配置设置让以上两个配置设置都不再有安全/最佳实践问题。
注意:如果您需要非特权用户来执行任何项目,请使用用户 ID 65535 的用户 nobody 。
只修改即可,不需要创建
做题解答:

<1> 修改 Dockerfile(修改Ubuntu的版本为16.04,一般不使用root来运行容器,这里改为使用nobody)
vi /cks/docker/Dockerfile
1、仅将 CMD 上面的 USER root 修改为 USER nobody,不要改其他的
USER nobody
2、修改基础镜像为题目要求的 ubuntu:16.04
FROM ubuntu:16.04
<2> 修改deployment.yaml
vim /cks/docker/deployment.yaml
1、securityContext字段中: 将 privileged 变为 False
2、securityContext字段中: 将 readOnlyRootFilesystem 变为 True
3、securityContext字段中: runAsUser: 65535

8、沙箱运行容器 gVisor

该 cluster 使用 containerd 作为 CRI 运行时。containerd 的默认运行时处理程序是 runc。
containerd 已准备好支持额外的运行时处理程序 runsc (gVisor)。
Task
使用名为 runsc 的现有运行时处理程序,创建一个名为 untrusted 的 RuntimeClass。
更新 namespace server 中的所有 Pod 以在 gVisor 上运行。
您可以在 /cks/gVisor/rc.yaml 中找到一个模版清单。
做题解答:
#前提:
在所有节点已经安装完成gvisor,之后可以进行一下操作
#ns
8-ns.yaml
 
apiVersion: v1
kind: Namespace
metadata:
  name: server
#runtimeclass
8-rc.yaml 

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: untrusted
handler: runsc
#deploy
8-deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox-run
  namespace: server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: busybox-run
  template:
    metadata:
      labels:
        app: busybox-run
    spec:
      containers:
      - name: busybox-run
        image: nginx
        imagePullPolicy: IfNotPresent
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-host
  namespace: server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-host
  template:
    metadata:
      labels:
        app: nginx-host
    spec:
      containers:
      - name: nginx-host
        image: nginx
        imagePullPolicy: IfNotPresent
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: run-test
  namespace: server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: run-test
  template:
    metadata:
      labels:
        app: run-test
    spec:
      containers:
      - name: run-test
        image: nginx
        imagePullPolicy: IfNotPresent
#编辑 deployment
kubectl -n server edit deployments busybox-run
kubectl -n server edit deployments nginx-host
kubectl -n server edit deployments run-test
#修改如下内容
spec: #下面有 containers 这个字段的 spec。  这里需要找一下是否已经有这个字段了。
   runtimeClassName: untrusted #添加这一行,注意空格对齐,保存会报错,忽略即可。
   containers:
   - image: nginx:1.9
     imagePullPolicy: IfNotPresent
     name: run-test
#验证
kubectl exec -it busybox-run-* -n server --  dmesg

9、网络策略 NetworkPolicy

Task
创建一个名为 pod-restriction 的 NetworkPolicy 来限制对在 namespace dev-team 中运行的 Pod products-service 的访问。
只允许以下 Pod 连接到 Pod products-service:
1.namespace qaqa 中的 Pod
2.位于任何 namespace,带有标签 environment: testing 的 Pod
注意:确保应用 NetworkPolicy。
做题解答:
#ns
9-ns.yaml 

apiVersion: v1
kind: Namespace
metadata:
  name: dev-team
---
apiVersion: v1
kind: Namespace
metadata:
  name: qaqa
  labels:
    ns: qaqa
#pod
9-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: products-service
  namespace: dev-team
  labels:
    app: nginx
spec:
  containers:
  - name: products-service
    image: nginx
    imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Pod
metadata:
  name: test
  namespace: qaqa
spec:
  containers:
  - name: test
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","echo hello && sleep 3600"]
---
apiVersion: v1
kind: Pod
metadata:
  name: test2
  labels:
    environment: testing
spec:
  containers:
  - name: test2
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","echo hello & sleep 3600"]
---
apiVersion: v1
kind: Pod
metadata:
  name: test3
  labels:
    environment: prod
spec:
  containers:
  - name: test3
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","echo hello && sleep 3600"]
#netpol
9-netpol.yaml 

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: pod-restriction
  namespace: dev-team
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          ns: qaqa
  - from:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          environment: testing

10、Trivy 扫描镜像安全漏洞

Task
使用 Trivy 开源容器扫描器检测 namespace kamino 中 Pod 使用的具有严重漏洞的镜像。
查找具有 High 或 Critical 严重性漏洞的镜像,并删除使用这些镜像的 Pod。
注意:Trivy 仅安装在 cluster 的 master 节点上,
在工作节点上不可使用。
你必须切换到 cluster 的 master 节点才能使用 Trivy。
做题解答:
#安装trivy
wget https://github.com/aquasecurity/trivy/releases/download/v0.50.1/trivy_0.50.1_Linux-64bit.deb
dpkg -i trivy_0.50.1_Linux-64bit.deb
trivy image <image name>:<image tag>
#测试pod
10-pod.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: kamino
---
apiVersion: v1
kind: Pod
metadata:
  name: test
  namespace: kamino
spec:
  containers:
  - name: test
    image: nginx:1.18
    imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Pod
metadata: 
  name: test2
  namespace: kamino
spec:
  containers:
  - name: test2
    image: nginx:1.19
    imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Pod
metadata:
  name: test3
  namespace: kamino
spec:
  containers:
  - name: test3
    image: nginx
    imagePullPolicy: IfNotPresent
#检测
master 节点才能使用 Trivy
kubectl describe pod -n kamino |grep "Image:"|awk '{print $2}' > 1.txt  #获取命名空间下的所有镜像
for i in `cat 1.txt`; do trivy image -s HIGH,CRITICAL $i > $i.txt; done
#单独检测
trivy image nginx:1.19 | grep -iE 'High|Critical'
#删除pod
kubectl delete pod xxx -n kamino 

11、AppArmor

Task
在 cluster 的工作节点 node02 上,实施位于 /etc/apparmor.d/nginx_apparmor 的现有 APPArmor 配置文件。
编辑位于 /cks/KSSH00401/nginx-deploy.yaml 的现有清单文件以应用 AppArmor 配置文件。
最后,应用清单文件并创建其中指定的 Pod 。
请注意,考试时,考题里已表明 APPArmor 在工作节点上,所以你需要 ssh 到开头写的工作节点上。
做题解答:
#apparmor 文件放在node节点
vim /etc/apparmor.d/nginx_apparmor
#include <tunables/global>
profile nginx-profile-3 flags=(attach_disconnected){
  #include <abstractions/base>
  file,
  deny /bin/** w,
  deny /data/www/** w,
}
#加载启用这个配置文件,以下2种方法都可以
apparmor_parser -q /etc/apparmor.d/nginx_apparmor    
apparmor_parser -r /etc/apparmor.d/*
#pod
11-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: apparmor-pod
  annotations:
    container.apparmor.security.beta.kubernetes.io/apparmor: localhost/nginx-profile-3
spec:
  containers:
  - name: apparmor
    image: busybox
    imagePullPolicy: IfNotPresent
    command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
#测试结果如下:
kubectl exec apparmor-pod -- touch /data/www/1.txt
touch: /data/www/1.txt: Permission denied

12、Sysdig & falco

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

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

注:确保事件文件存储在集群的工作节点上。
做题解答:

13、Container 安全上下文

Context
Container Security Context 应在特定 namespace 中修改 Deployment。
Task
按照如下要求修改 sec-ns 命名空间里的 Deployment secdep
一、用 ID 为 30000 的用户启动容器(设置用户 ID 为: 30000)
二、不允许进程获得超出其父进程的特权(禁止 allowPrivilegeEscalation)
三、以只读方式加载容器的根文件系统(对根文件的只读权限)
做题解答:
13-deploy.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: sec-ns
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: secdep
  namespace: sec-ns
spec:
  replicas: 2
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - name: busybox
        image: busybox
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh","-c","echo hello && sleep 3600"]
        securityContext:
          runAsUser: 30000
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
#验证
/ $ top
Mem: 1913624K used, 92392K free, 14352K shrd, 24388K buff, 1142532K cached
CPU:  0.0% usr  0.0% sys  0.0% nic  100% idle  0.0% io  0.0% irq  0.0% sirq
Load average: 0.06 0.08 0.15 1/535 14
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
    7     0 30000    S     1332  0.0   1  0.0 sh
   14     7 30000    R     1328  0.0   0  0.0 top
    1     0 30000    S     1316  0.0   1  0.0 sleep 3600
/ $ touch 1.txt
touch: 1.txt: Read-only file system

14、删除非无状态或非不可变的 pod

Task
检查在 namespace production 中运行的 Pod,并删除任何非无状态或非不可变的 Pod。
使用以下对无状态和不可变的严格解释:
a.能够在容器内存储数据的 Pod 的容器必须被视为非无状态的。
b.被配置为任何形式的特权 Pod 必须被视为可能是非无状态和非不可变的。
注意:你不必担心数据是否实际上已经存储在容器中。
做题解答:
#pod
14-pod.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: production
---
apiVersion: v1
kind: Pod
metadata:
  name: test1
  namespace: production
spec:
  containers:
  - name: test1
    image: nginx
    imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Pod
metadata:
  name: test2
  namespace: production
spec:
  containers:
  - name: test2
    image: nginx
    imagePullPolicy: IfNotPresent
    securityContext:
      privileged: true
---
apiVersion: v1
kind: Pod
metadata:
  name: test3
  namespace: production
spec:
  containers:
  - name: test3
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: log
      mountPath: /var/log/nginx
  volumes:
  - name: log
    emptyDir: {}
#查看具有特权的 pod
kubectl get pods -n production -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.namespace}{"\t"}{.spec.containers[*].securityContext.privileged}{"\n"}{end}' | grep 'true'
#查看具有 volume 的 pod
kubectl get pods -n production -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{range .spec.volumes[*]}{.name}{" "}{end}{"\n"}{end}' | awk '{ if (NF > 2) print $1 }'
#将查询到的具有特权和 volume 的 pod 都删除
kubectl delete pods -n production pod名称

15、启用 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 ,以确保经过身份验证的授权的请求仍然被允许。
做题解答:
#任务一 确保只有认证并且授权过的 REST 请求才被允许
vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --authorization-mode=Node,RBAC        #注意,只保留 Node,RBAC 这两个。可能默认已经有了,但还是要检查确认一下。
- --enable-admission-plugins=NodeRestriction 				#原先为 AlwaysAdmit,需要修改为 NodeRestriction。

重启kubelet
systemctl daemon-reload
systemctl restart kubelet
#任务二 删除题目要求的角色绑定
kubectl get clusterrolebinding -o yaml | grep system:anonymous    #查看所有的clusterrole绑定的角色
kubectl delete clusterrolebinding system:anonymous  #删除clusterrolebinding

16、TLS 安全配置

Task
通过 TLS 加强 kube-apiserver 安全配置,要求
1、kube-apiserver 除了 VersionTLS13 及以上的版本可以使用,其他版本都不允许使用。
2、密码套件(Cipher suite)为 TLS_AES_128_GCM_SHA256
通过 TLS 加强 ETCD 安全配置,要求
1、密码套件(Cipher suite)为 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
做题解答:
#可参考
kubectl exec -it -n kube-system kube-apiserver-k8smaster -- kube-apiserver -h|grep tls
#修改 kube-apiserver,修改之前需备份
vim /etc/kubernetes/manifests/kube-apiserver.yaml
添加或修改相关内容,并保存(先检查一下,如果考试环境里已经给你这两条了,则你只需要修改即可)
 - --tls-cipher-suites=TLS_AES_128_GCM_SHA256
 - --tls-min-version=VersionTLS13
#修改 etcd,修改之前需备份
vim /etc/kubernetes/manifests/etcd.yaml
添加或修改相关内容,并保存
- --cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
#重启
systemctl daemon-reload
systemctl restart kubelet
systemctl restart etcd 
如果出现:Failed to restart etcd.service: Unit etcd.service not found.,可以查找kube-system下的etcd,例如
kubectl delete po etcd-controlplane -n kube-system

#验证 修改完成后,等待3分钟,等集群应用策略后,再检查所有 pod,特别是etcd和kube-apiserver两个pod,确保模拟环境是正常的。
kubectl get pod -A
kubectl -n kube-system get pod
ps -ef|grep etcd  #可以看看是否集成进去

17、ImagePolicyWebhook 容器镜像扫描

Context
cluster上设置了容器镜像扫描器,但尚未完全集成到 cluster 的配置中。
完成后,容器镜像扫描器应扫描并拒绝易受攻击的镜像的使用。
Task
注意:你必须在 cluster 的 master 节点上完成整个考题,所有服务和文件都已被准备好并放置在该节点上。
给定一个目录 /etc/kubernetes/epconfig 中不完整的配置,
以及具有 HTTPS 端点 https://image-bouncer-webhook.default.svc:1323/image_policy 的功能性容器镜像扫描器:
1. 启用必要的插件来创建镜像策略
2. 校验控制配置并将其更改为隐式拒绝(implicit deny)
3. 编辑配置以正确指向提供的 HTTPS 端点
最后,通过尝试部署易受攻击的资源 /cks/img/web1.yaml 来测试配置是否有效。
做题解答:
image_policywebhook的部署是通过一个服务来完成的,https://image-bouncer-webhook.default.svc:1323/image_policy,
考试的时候,这个服务是已经部署好的,因此,我们不需要关心这个服务是否部署,是以何种形式部署的,只需要知道该服务是可用的即可。
imagePolicyWebhook是需要apiserver引用的,因此,我们需要更改apiserver以插件的形式使用这个功能。
最后需要执行/cks/img/web1.yaml,如果此pod部署失败,表示imagePolicyWebhook插件启用成功。
#第 1 步,编辑 admission_configuration.json(题目会给这个目录),修改 defaultAllow 为 false:
vi /etc/kubernetes/epconfig/admission_configuration.json       #修改准入控制器的json文件
……
 "denyTTL": 50,
 "retryBackoff": 500,
 "defaultAllow": false #将 true 改为 false
……
#第 2 步,操作前,先备份配置文件,编辑/etc/kubernetes/epconfig/kubeconfig.yml,添加 webhook server 地址:
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
……
#第 3 步,操作前,先备份配置文件,编辑 kube-apiserver.yaml,从官网中引用 ImagePolicyWebhook 的配置信息:
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 考试中,蓝色的内容可能已经有了
   - mountPath: /etc/kubernetes/epconfig #建议紧挨着 volumeMounts 的下方增加
     name: epconfig
     readOnly: true
# 在 kube-apiserver.yaml 的 volumes 增加
 volumes: #在 volumes 下面增加 #注意,在 1.25 考试中,蓝色的内容可能已经有了,你只需要检查确认一下是否准确
   - name: epconfig     #建议紧挨着 volumes 的下方增加
     hostPath:
       path: /etc/kubernetes/epconfig
       type: DirectoryOrCreate       #如果你写的是目录,则是 DirectoryOrCreate,如果你写的是文件,则是 File
#第 4 步,重启
systemctl restart kubelet        #等待 3 分钟,等集群应用策略后,确保 kube-apiserver 是 running 的
#验证
kubectl -n kube-system get pod   #通过尝试部署易受攻击的资源 /cks/img/web1.yaml 来测试配置是否有
kubectl apply -f /cks/img/web1.yaml  #无法创建 pod,如下报错,表示成功。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值